« Catching up on Storytellers Contest Winners | Main | What is this Stingray Traffic Manager, anyway? Part 5: Deployment »

November 21, 2011

On the importance of secure software layers

Writing high quality software is difficult. Writing secure high quality software is even more difficult. Perhaps because software is still a relatively young discipline, certain aspects present real challenges:

  • Its specification languages allow for a broader interpretation of procedures and tasks
  • Its product attracts a disproportionate number of attackers
  • Its behavior is difficult to predict when its environment or use patterns extend beyond design assumptions

Let's compare software engineering to civil engineering. Humans have been building bridges for a few thousand years. If you follow the specifications for building a bridge, what do you get? Why, a bridge, of course. No tiny unsuspected houses emerge hanging from one side, for example.

TacomaNarrowsBridgeCollapse_in_colorHow many rivets are in the Golden Gate Bridge? (Answer.) If you selected two dozen at random and removed them, would the bridge spectacularly collapse into the San Francisco Bay? Of course not. Aside from a few notable failures, bridges are well-understood constructions. We can predict how a bridge will behave according to its specifications, we can predict how a damaged bridge will behave in the face of local failures, and we can predict how a deteriorating bridge will continue to function before certain repairs are required.

How many lines of code are in Debian 5.0? (Answer.) If you randomly commented two dozen lines and recompiled the code, can you predict how it would behave? Not a chance. It might run for days, weeks, even years -- or it might crash immediately. Can you fully predict how any particular installation will behave, given the vast possibilities of how the individual components might be (mis-)configured? Not during your natural lifetime.

Imagine you're writing a program, and consider the illustration below. The green circle represents your expected behavior; the blue circle represents your program's actual behavior:

Behavior and bugs

All code has bugs, of course. Traditional bugs we can find and eliminate because they become obvious through testing: we expect certain behavior but instead we notice something wrong, so we re-examine the code, find the mistake, and fix it. Traditional bugs manifest themselves when we don't see what we expect to see.

Hacker1Security bugs are almost always the opposite: non-obvious behavior that has somehow crept into our code, behavior that we don't know is there and don't really know to test for very well. Security bugs manifest themselves when we see what we don't expect to see. And people who specialize in attacking software are very, very good at seeking out the unexpected.

Earlier this summer my teenage son enrolled in a week-long summer camp to learn Java programming. On demonstration day, at the end of the course, parents were invited to view the projects their children had worked on during the week. My son created a simple text-based blackjack game. As I examined the code, I noticed well-formed structure and concise comments throughout. When I executed the program, it greeted me with this prompt:

Welcome to Blackjack!
Please select (1) to play or (2) to end:

Well, what do you think I did? As any proud parent would, I violated the instructions and entered "4." The program immediately crashed and dumped me into a debugger. My son couldn't figure out why I ignored the prompt! "Four isn't a choice, why didn't you pick one or two?" he asked. "Not everyone operates your software in only the ways you'd expect, you know," I replied. "Who would ever do that?" Heh. On the way home we discussed the importance of input validation and exception handling. You have to learn how to think like a bad guy if you don't want bad guys breaking your code.

Foundationally, there's no substitute for writing secure, resilient software -- software that expects to be abused, defends itself when under attack, and fails safely. Ross Anderson's book Security Engineering belongs on every developer's bookshelf, e- or otherwise. Build Security In is another excellent source for materials that can help you incorporate improved security coding practices into your software development programs.

EnforcerOn top of this critical foundation, additional layers help increase your defense. Because so much of today's software runs on the web, attacks against web applications outpace all others. Specific tools like our Stingray Application Firewall can help protect web applications from several attack vectors. Exploits of common vulnerabilities often present in third-party software can be detected and blocked. Path restriction and request/reply validation rules can thwart attempts to force web applications to misbehave. And over time, execution heuristics can suggest additional protective measures.

Software is under tremendous attack. Whether it's attacks against availability (denial of service), attacks against confidentiality (eavesdropping and interception), or attacks against integrity (malicious modification), the volume and impact show no signs of abating. Fortunately, the tools we have to defend ourselves against attack exhibit a wide diversity of detection and defensive capabilities, with increasing effectiveness and sophistication.

TrackBack

TrackBack URL for this entry:
http://www.typepad.com/services/trackback/6a00e5508a3ca7883401539357db19970b

Listed below are links to weblogs that reference On the importance of secure software layers:

Comments

Feed You can follow this conversation by subscribing to the comment feed for this post.

Post a comment

This weblog only allows comments from registered users. To comment, please Sign In.


WWW
blogs.riverbed.com

Please enter your email address to subscribe to the Riverbed Blog:

Please enter your email address to subscribe to the Riverbed Blog: