Wednesday, July 13, 2011

Programmers and firewalls

OK, this one's going to be nerdy. If you're not a programmer, you'll want to surf elsewhere. If you're a programmer, please read and learn. If you're a network engineer or firewall admin, read and sympathise.

Executive summary:

Don't put your programs on weird TCP (or UDP) ports. Just don't. It doesn't help your security at all, and it blocks you from a bunch of legitimate users.

End Executive Summary



So I'm currently implementing a multi-site firewall and VPN installation, and it's pushing one of my pet peeve buttons hard.

First, Background:
One of the things I strongly support is egress filtering. Many or most firewall admins don't do this, and allow anybody inside out on any port at any time for any reason. That's fine until one of the "protected" machines gets compromised (and they will), at which point it has nothing preventing it from phoning home to the cracker that owned it and joining his botnet, to be used for future evil. Egress filtering at reduces this a little (he has to use an open port, not his "special" one), and if you combine it with some pattern matching, you might catch compromised boxes sooner (hey, the server at tweek.example.net just started generating a bunch of outbound traffic we've never seen before, what's up with that????")

So I do egress filtering. It's no silver bullet, but I think it helps.


The week after you bring up a new firewall, you always have to spend a few days punching additional holes in it for things you either didn't think of or didn't know about.

(Punching holes in the firewall is bad, MMMMkay?)

Stuff you didn't think of is on you. Bad Network Engineer! No Tee Shirt! Unpaid overtime instead!

Stuff you didn't know about is often (6 cases so far, and counting....) the fault of some programmer that got lazy or was ignorant and decided to put their application on a nonstandard TCP port. Case in point, I've discovered a webserver outside my firewall that goes along fine (on 80/443) until you do a search, and then the URL jumps to "http://lame.server.example:3442/rest/of/url"

Whoever wrote the search took it off 80/443 and put it on a nonstandard port. Just because.

There are two reasons I can think of why this turns out this way:

Laziness: Progammer doesn't want to take the time to learn and implement this in a way that integrates it with apache or IIS or whatever. No excuse for this. You don't want to be this programmer, you'll be re-inventing the wheel. Insecurely.

Ignorance / false sense of security: The programmer thinks "webservers get compromised all the time (True), I'll stick my listener on a weird port where no one will find me" (False). You don't want to be this programmer either.

I used "False sense of security" pretty deliberately. Twice now. Here's the deal: Any attacker with any chops at all, which is to say any attacker you should be worried about, is going to scan your box for open ports. Even if he weren't going to scan you (and he will) don't forget that "http://lame.server.example:3442/rest/of/url" is publicly available in the hyperlinks throughout the rest of your website, and that big fat :3442 hanging out there looks like a "hack me here" sign. So your hidden port is anything but, and of course your code is less likely to be both examined and updated for security fixes than Apache's. Or Microsoft's. Or anybody's. You might lose a few anklebiters, but only the ones too lame to download nmap. All the ones you should be worried about will be right there, Hackin ur box on ur nonstandard portz.

Worse, you're making your life (and the lives of a bunch of well, not innocent, but.... otherwise uninvolved... firewall and network admins) a hell, forever. You'll have to answer endless questions about why it doesn't work and what the app does and why it's off on a weird port. Not the sort of thing you want to do with your day. The network/firewall guy at your office will have to poke a hole for your app inbound, and that'll probably expose machines next to yours, because network people hate doing things for single hosts (that's an easy way to slow the firewall to a crawl). Are you sure you didn't pick a random port that's being used for some crummy code that's full of exploits and being hammered on constantly? Are you willing to BE sure? Every day??? Even if your code is perfect (hah!), you don't need all this exploit traffic hammering on you all day every day. Plus you just talked your firewall admin into exposing the machine next to yours, which may be vulnerable.

Worst of all, at the other end of the Internet are.... Your customers. Lots of them (more every day) have firewalls and egress filters and can't reach you because their firewall doesn't let them out on 3442. You're essentially limiting your customer base to people who are willing to poke holes in their firewalls for little or no reason. If the remote firewall admin accommodates programmers like you, he'll end up with a long, complex, slow rule base that's full of holes. If he doesn't, then his users just don't get to use your app. There ought to be a joke here about limiting your customer base to newbs and lame-os but I'm too tired and pissed to think it up.

So it's the worst of both worlds. You don't lose any of the evil intruders, and you do end up losing a lot of legitimate users. Plus you're pissing off your firewall admin. He can cut off your Internet, don't you know? Or even replace your internet with kittenwar

Take a lesson from the crackers. Put everything on 80 and 443(*). You'll fly through all the firewalls in the world, and no one will ever know, and your application will just WORK and you won't have to spend your time answering questions and writing up how-tos on getting around the corporate firewall.

Plus, though there'll be no money, on your deathbed you'll receive total consciousness. So you'll have that going for you. Which is nice...

(*)No, it doesn't actually have to be web traffic. It'll look like web traffic to yobs like me, and fly through. Which is what you want.