March 14, 2007, 12:47 p.m.
posted by oxy
Item 58: Remember that security is not just preventionLet's ignore the software world for just a second. If we're looking for good models of how to build secure systems, to at least a certain degree we can go back to "the real world" for examples of what works and what doesn't. Within the real world, in an era where automated video cameras, electric fences, motion detectors, and zone alarms are the norm, simply preventing an attacker's entry into the system is not nearly enough. Consider European history for a moment—in the Middle Ages, the pinnacle of defense was the classic castle: stone walls a yard or two thick, rising thirty or more feet into the air, surrounded by a large body of water that made approaching the base of the walls difficult if not impossible. Given this impregnability, certainly it would seem that the castle (at least until the invention of gunpowder) represented an absolutely unassailable target. So why, then, did every castle keep guards? If the castle itself was so impregnable, why pay men to wander the tops of the walls, doing nothing but watching for any attempts at intrusion? For a modern parallel, think about the car alarm—what makes us believe that a shrieking wail will drive a prospective car burglar away? Is it the fact that the sound is loud enough to cause physical harm? Of course not. The castle, unmanned, will eventually be taken—somebody will figure out that a ladder is of tremendous help here. The car, shrieking its alarm in the middle of an empty parking lot, will get stolen once the thief realizes that nobody's coming to stop him. Simple prevention, trying to keep the attacker from gaining entry, is not enough; physical deterrence will only slow an attacker, not stop him. The other two parts of any secure system are detection and reaction. Go back to the castle again. When the invading army shows up, the guards at the top of the castle wall are going to immediately notify the rest of the castle inhabitants that some unfriendly folks have just arrived. The castle lord will immediately call out the rest of his troops, who will take up some rather persuasive means of denying entry: swords, crossbows, boiling oil, that sort of thing. When the enemy attacks the castle, the guards will react, trying to deny the enemy access to the castle, typically by engaging in some barbaric actions, like pouring the boiling oil on top of the attackers, or firing arrows at them, or pushing over their scaling ladders. The guards are not simply going to stand idly by and watch the bad guys climb the walls and lower the drawbridge—they will react with appropriate force to deny the attackers entrance. That's what they get paid for, at least in theory. The burglar alarm works the same way. I lock the doors on my house and my car to prevent an attacker easy entrance into my house or vehicle, but there are methods to get in without having to go through the doors: windows are one easy way in. (An enterprising house burglar in San Diego found another: use a chainsaw to create your own doorway in an otherwise plain wall.) So I put sensors on the windows; if they are broken, an alarm goes off and alerts not only me and my family but also the alarm company I write a check to every month. Either I or the alarm company, having detected the intrusion attempt, will immediately call the police, who will react by rushing to the scene and detaining the intruder, potentially using force if necessary. Other homeowners might react differently by making use of legitimately owned firearms kept by the bedside—the effect is the same. So if simple prevention won't work in real life, what on earth makes us believe it will work in software systems? The firewall will certainly prevent a large number of attacks against it, but what will it do if one happens to get through? How will you know you've been attacked? How will you respond? Unfortunately, again, this is an area where the software security industry falls seriously deficient. To be sure, intrusion detection systems are marketed and sold, but all of them carry a serious disadvantage: the false positive. The software packages periodically register benign traffic on the network as an intrusion attempt and start ringing the alarms. It turns out the attempt isn't actually an intrusion attempt; the software is reset and the system administrators go back to their daily grind. Why is the false positive such a bad thing? Go back to our earlier example of the car alarm: it relies on the idea that when the alarm goes off, somebody will hear it (detection) and call the police to stop the would-be burglar (reaction). When's the last time you did this when you heard a car alarm? In the early days of the car alarm, it was actually not uncommon for concerned citizens to rush to the source of the alarm when it went off, knowing that the alarm going off meant that somebody was trying to break into somebody else's car. After all, someday it could be my car getting burglarized, and I'd want people to stop the burglar then, right? But the problem was that lots of car alarms were set to be too sensitive to any sort of motion around or on the cars: trains or airplanes in close proximity to a vehicle were known to set off the alarm, as was accidentally bumping your car door into the alarmed vehicle, as was your three-year-old scampering away from you in the parking lot and running into the bumper. We learned, as human beings, that false positives happen far, far more often than true positives. We grew complacent to the idea that the alarm going off meant real trouble, and we eventually reached a point that when an alarm goes off, our reactions are either (a) curse the owner for not coming out to shut the stupid thing off, or (b) ignore it and continue whatever we were doing before it went off. This isn't a new problem—rebels and guerrillas have known for years that the best way to attack a military base isn't to go charging at the electrified gates, guns blazing. Guards with fancy military hardware drive around in Jeeps with machine guns or Armored Personnel Carriers with bigger guns, and a small rag-tag band of freedom fighters armed with rifles isn't going to last long against that kind of hardware. So instead, the rebels use stealth; they want to lull the guards into a false sense of security. The rebels find a rabbit or some other small animal, fling it against the fence, and melt away into the shadows. The perimeter alarms go off, and the guards come rushing, find the animal's smoking carcass on the fence, call it a false alarm, and go back to the barracks. The rebels do it again an hour later. The guards come rushing, realize it's just another animal, and head back to the barracks. After three or four more of these, the guards are desensitized to the alarm—they may not even bother sending out a patrol to check the gates. That's when the rebels pull out the cutters, cut a hole in the fence (which is what the alarms were supposed to warn against, but by this time they're either ringing to no effect or the guards have just turned the silly things off), sneak in, and do their deadly deeds. Think this tactic isn't successful? The mujahedin used it time and time again against their Soviet occupiers in Afghanistan in the 1980s. The Kosovars used it against their Serbian occupiers in Yugoslavia in the 1990s. It's probably what let the small outboard rowboat laden with explosives get so close to the USS Cole ("Eh, it's just another motorboat, Jack—it's not like it's a real threat"). Think this tactic isn't being used against your company? That all depends on whether the company even has any sort of intrusion detection software in place; many don't. Those that do, however, are flooded with hundreds, if not thousands, of false positive intrusion attempts every day, and system administrators get tired of it, enough to turn the alarms down or altogether off. What does this mean from a programmer's perspective? It means that your software, in order to be administration-friendly (see Item 13), should have detection and reaction mechanisms laced throughout it wherever possible. The classic tactic, of course, is to allow only a finite number of bad logins before locking the user's account in a way that only an established, trusted system administrator can unlock. If your servlet starts to get malformed input that should have been caught by client-side validation code (JavaScript in the HTML browser, for example), it's possible that an attacker is attempting to find the edges of your system's security; notify an administrator and/or log the source of the communication, the number of attempts, and so on. At every point in your threat model (see Item 59), put code to detect what might be an intrusion attempt, log it, and notify an administrator somehow. Be careful to make the notification intrusive enough to get somebody's attention but not so intrusive that people are tempted to shut it off in the inevitable event of false positives. (E-mail works well for this, or a text message to a cellphone or pager sometimes works.) At the end of the day, software can't just rely on prevention—detection and reaction have to be there too, or we might as well not even bother with prevention in the first place. |
- Comment