Larry Osterman's post (er, rant) (found here - http://blogs.msdn.com/larryosterman/archive/2007/11/02/chris-pirillo-s-annoyed-by-the-windows-firewall-prompt.aspx) about someone's gripe with Firefox and the firewall caused me to remember to add to the discussion. Larry claims:
"IMHO outbound firewalls are 100% security theater. They provide absolutely no value to customers. This has been shown time and time again…"
I'm familiar with this argument, since I've made the same point in the past. There are two major exceptions that I think are worth making. The first is that if you're putting an app in a sandbox, there isn't much available to restrict what it can do on the network. Sadly, the job objects can do a lot of cool stuff, but it cannot prevent an app from obtaining a socket handle. What it does do for you is that it prevent transparent Windows authentication across the network. This is a lot nicer than how integrity levels currently function – I can start a command prompt running as low and administer my Win2k3 dev system across the network, which isn't something I'd like gremlins loose in Protected mode IE to be able to do.
Your sandboxed app running under a restricted token isn't going to be able to go out and raid your shares, admin your other system, etc, but it can open a socket and either listen or connect out. Ideally, I'd like to be able to set some flags in the job object to stop this, but in Vista and later, I can use the firewall rules so that if my sandboxed application has a process name I can depend on, then I can set rules to stop it from either making outbound connections or accepting inbound connections. I documented how to do this in Chapter 4 of Writing Secure Code for Windows Vista. As a shameless plug, I think the book can save you $24.95 worth of cursing just from being able to see how this stuff actually works, and there's sample code you can use, too.
The interesting thing is that the behavior of the restricted token with respect to Windows auth is completely by design – they'd anticipated the problem of a loopback attack leading to an EoP, and faced with a bunch of hard work to make it do something complicated, they just stopped it. I wish they'd done the same thing with the integrity level stuff – or at least made it an option when creating the process. OTOH, they had plenty of work to do shipping ILs at all, and we should see them improved over time.
In this case, the outbound firewall isn't security theater at all. The sandboxed app doesn't have anything close to the level of permissions needed to alter the firewall, and the user won't see any prompts that they can dismiss. Any malware that gets loose in the sandbox just dies the horrible death it deserves when stuff it depends on just isn't there and bind() or connect() returns unexpected errors.
The second scenario where it does provide value is when the user isn't running as admin, and any malware also doesn't have the rights to change the firewall rules.
Another thing to think about is Adam Shostack's point that we don't have to make it perfect to make it better. A dog is an extremely flawed intrusion detection system for houses, but data clearly shows that houses with dogs have a lot fewer burglaries. If the malware isn't expecting an outbound firewall, it will be much more likely to fail or reveal itself to the owner of the system.