Breaking Away from SQL Injection and Buffer Overflows
Whether they are stealing credit cards or breaking into banks, criminals have made things like SQL Injection attacks into “the new buffer overflow,” meaning that SQL injection is one of the most prevalent vulnerabilities on the net today. Lots of people on the Internet will tell you how to fix a web page that is vulnerable to SQL Injection and many tools can tell you when you have a buffer overflow vulnerability. These things are good, but they are attacking the problem piecemeal. If you’re managing software security inside an organization, I have another idea. Attack it earlier in the lifecycle, preferably in the Requirements and Design stage.
Like many buffer overflow attacks, SQL Injection relies on a system’s willingness to accept input that falls outside the scope of an acceptable data specification. In short, it’s garbage, posing as tonight’s entrée. If you put controls in place to sniff out the garbage, you can protect yourself from many of the bad things that happen to web sites today. This also goes back to my running theme about addressing security throughout the lifecycle, instead of isolating your effort to the coding or test phase.
If you’re curious about the vulnerabilities discussed in this post, here are good links to basic info on SQL Injection and Buffer Overflow. (Thanks Wikipedia.)
As you can see, these attacks (and others) rely on applications that fail to verify input. The problem here is that most application designers don’t spend a lot of time specifying input and subsequently, don’t spend a lot of time designing input verification mechanisms. For example, a person’s name might contain a hyphen ‘-‘ or an apostrophe (‘). They are not alphabetic characters, but they are the only non-alpha characters that would reasonably be part of a person’s name. Right? Believe it or not, some people use numbers in their names. However, very few people use the backslash ‘\’. Knowing this, we can specify rules about the name field in the requirements phase of our application design.
Take this single problem and multiply it by the variety of input fields in the standard web application. If you attempt to solve the problem piecemeal, you will waste a lot of time. For that reason, it’s better to design an input processor that can verify the basic information received by your application and also check for garbage that might damage your system. How is that done?
First, you define the types of input you need and specify the range of values that may be assigned to specific fields. Does any numeric value need to be larger than 32 million? Can you differentiate between short strings (up to 256 bytes) and long strings? Do you need to canonicalize any of your input data, such as for URLs? If a specific input value will never need to record ‘\’ ‘/’ ‘%’ or other known escape characters, can you legally scrub it from the string before passing it along?
In the design phase, design some form of input verification routine that will use available system calls to fix data before it is passed along to the application. Input validation should be something that is consistent and parameterized so that the calling routine can provide meta data about the destination field. Doing so will give you a more robust way to reuse the code.
Once you know what you need, don’t build it all yourself. Different development environments provide tools to help with this. Look at input validator routines for .NET or possibly using Strategy Patterns in Java or PHP. Whatever you implement, try to stick as close as possible to your specification. That way, you are less likely to allow garbage into your application.
Once you’ve built an input validation process, test this mechanism with fuzzing tools to make sure that it performs as advertised. You might also consider extending this routine to include checking for naughty words or inappropriate submissions. There are many ways to structure the functionality of this mechanism so that it improves the resilience of your application.
If you follow these steps you are less likely to fall victim to the next attack. As you can see, many input problems we see today result from our unwillingness to specify and validate input. Start this process earlier in your SDLC to be sure that you don’t get bitten by the same set of bugs.
Jim Molini, CISSP, CSSLP
