Buffer overflow is a common enough problem that most applications face. So how does a software developer ensure that his/her application is safe from buffer overflows?
- Secure Designing and Coding
- Configure non-executable stack
- Use safer versions of functions
- Use of safe libraries.
- Use tools.
- Any of the above.
Well I guess any of the above or even combinations of the above could be implemented by software developers to prevent/detect buffer overflows.
- Secure Designing and Coding - The most effective way to avoid the buffer overflow problem is to code securely. Usually while designing an application the security features are not paid any attention. Applications should be designed with security in mind.
- Configure non-executable stack – In this case disable the stack to hold any executable code. This requires the kernel to be recompiled. Patches are available for both Linux and Solaris for configuring a non-executable stack. This method prevents stack-based buffer overflow attacks only.
- Use safer versions of functions – All the unsafe functions like strcpy and sprintf have their "safe" counterparts that can be substituted, such as strncpy and snprintf, which in addition to the buffers also take a size parameter. So replacing the functions with safe versions is another solution.
- Use of safe libraries – A programming language includes library files. So if there is a weakness with a particular library file, any application that includes that particular library file also has the weakness.
One approach is to use Library-based defenses that have re-implemented unsafe functions and ensure that these functions can never exceed the buffer size. An example is the Libsafe library. It provides a way of securing calls to these functions by replacing the implementation of the unsafe functions in the shared libc library with safe versions. Another approach is to use library-based defenses that detect any attempt to run illegitimate code on the stack. So in case if the stack smashing attack has been attempted, the program responds by emitting an alert. This is a solution implemented in the SecureStack developed by SecureWave.
- Use tools - There are a number of tools that can help detect buffer overflow vulnerabilities:
- In the source code - A source code tool analyzes the source code of a program and tries to determine whether it contains any unsafe code that could lead to buffer overflows. E.g. of such tools are Flawfinder, Viega's RATS, SPLINT and ITS4.
- Detection during runtime –Lets see what are the tools that can be used based on the type of defenses:
- Canary-based defenses - It modifies the compiler so that a "canary" value is inserted in front of the return address. Before a function returns, it checks to make sure that the canary value hasn't changed. Stackguard uses this method.
- Adding bounds to all buffers – The compiler adds code for keeping track of the size of buffers and checks that every buffer access falls within the allocated size. E.g. are Compaq C Compiler and Jones & Kelly's GCC patch.
- Protect the return address from being overwritten – Write the return address to a different place at the start of a function and if a buffer overflow exploit overwrites the return address on the stack, it is set back to the original value when the function returns. Since the function can call other functions which in turn need to store their return addresses we will need a stack to keep track of all the stored return addresses. This solution thus means separating the stack used for return addresses from the stack used for local variables. e.g. Stack Shield, a development tool.