OWASP Guide to Building Secure Web Applications and Web Services, Chapter 17: Buffer Overflows

Follow this chapter of the OWASP Guide to Building Secure Web Applications and Web Services to make sure applications aren't exposed to faulty components, make sure applications create as few buffer overruns as possible, and encourage the use of languages and frameworks that are relatively immune to buffer overruns.

This Content Component encountered an error

This article is provided by special arrangement with the Open Web Application Security Project (OWASP). This article is covered by the Creative Commons Share-Alike Attribution 2.5 license. You can find the latest version of this article and more free and open application security tools and documentation at http://www.owasp.org.


Buffer Overflows

Objective
To ensure that:

  • Applications do not expose themselves to faulty components
  • Applications create as few buffer overruns as possible
  • Encourage the use of languages and frameworks which are relatively immune to buffer overruns.

Platforms Affected
Almost every platform, with the following notable exceptions:

  • J2EE – as long as native methods or system calls are not invoked
  • .NET – as long as /unsafe or unmanaged code is not invoked (such as the use of P/Invoke or COM Interop)
  • PHP – as long as external programs and vulnerable PHP extensions written in C or C++ are not called.

Relevant COBIT Topics
DS11.9 – Data processing integrity

Description
Attackers use buffer overflows to corrupt the execution stack of a web application. By sending carefully crafted input to a web application, an attacker can cause the web application to execute arbitrary code - effectively taking over the machine. Attackers have managed to identify buffer overflows in a staggering array of products and components.

Buffer overflow flaws can be present in both the web server or application server products that serve the static and dynamic aspects of the site, or the web application itself. Buffer overflows found in widely used server products are likely to become widely known and can pose a significant risk to users of these products. When web applications use libraries, such as a graphics library to generate images, they open themselves to potential buffer overflow attacks. Literature on the topic of buffer overflows against widely used products is widely available.

Buffer overflows are found in custom web application code, and may even be more likely given the lack of scrutiny that web applications typically go through. Buffer overflow attacks against customized web applications can sometimes lead to interesting results. In some cases, we have discovered that sending large inputs can cause the web application or the back-end database to malfunction. It is possible to cause a denial of service attack against the web site, depending on the severity and type of the flaw. Over-large inputs may cause the application to output a detailed error message that may lead to a successful attack on the system.

Stack Overflow
Stack overflows are the best understood and the most common form of "buffer" overflows. The basics of stack overflows are simple:

  • There are two buffers. The source buffer contains arbitrary attack input, and the destination buffer is too small to contain the attack input. The second buffer needs to be on the stack and somewhat adjacent to the function return address on the stack.
  • The faulty code does not check that the first buffer is too big for the second buffer. It copies the hostile data into the second buffer, obliterating the second buffer and the function return address on the stack.
  • When the function returns, the CPU unwinds the stack frame and pops the return address from the stack. The return address is now polluted and points to the attack code.
  • The attack code is executed instead of returning to the application's previous caller.

How to determine if you are vulnerable
If your program:

  • Is written or depends on a program written in a language that suffers from buffer overflows AND
  • Takes input from a user AND
  • Does not sanitize it AND
  • Uses stack allocated variables without any canary values

It is likely that the application is vulnerable to attack.

How to protect yourself

  • Deploy on systems capable of using no execute stacks (AMD and Intel x86-64 chips with associated 64 bit operating systems: XP SP2 (both 32 and 64 bit), Windows 2003 SP1 (both 32 and 64 bit), Linux after 2.6.8 on AMD and x86-64 processors in 32 and 64 bit mode, OpenBSD (w^x on Intel, AMD, Sparc, Alpha and PowerPC), Solaris 2.6 and later with noexec_user_stack enabled.)
  • Use programming languages other than C or C++.
  • Validate user input to prevent overlong input and check the values to ensure they are within spec (ie A-Z, a-z, 0-9, etc.).
  • If relying upon operating systems and utilities written in C or C++, ensure that they use the principle of least privilege, use compilers that can protect against stack and heap overflows, and keep the system up to date with patches.

Heap Overflow
Heap overflows are problematic are they are not necessarily protected by CPUs capable of configuring no execute stacks. A heap is an area of memory allocated by the application run time to store locally declared variables.

function foo(char *bar) {
char thingy[128];
…
}

"bar" is passed via the stack, whereas "thingy" is allocated on the heap. The overflow possibilities are exploitable in exactly the same fashion as stack overflows.

How to determine if you are vulnerable
If your program:

  • Is written or depends on a program written in a language that suffers from heap overflows AND
  • Takes input from a user AND
  • Does not sanitize it AND
  • Uses heap allocated variables without any canary values

It is likely that the application is vulnerable to attack.

How to protect yourself

  • Use programming languages other than C or C++.
  • Validate user input to prevent overlong input and check the values to ensure they are within spec (ie A-Z, a-z, 0-9, etc.).
  • If relying upon operating systems and utilities written in C or C++, ensure that they use the principle of least privilege, use compilers which can protect against heap overflows, and keep the system up to date with patches.

Format String
Format string buffer overflows are caused when the user inputs something similar to:

%08x.%08x.%08x.%08x.%08xn

The above attack string will print the first five entries on the stack. Format strings are highly specialized buffer overflows and can be used to perform all the same types of attacks, including complete remote compromise.

How to determine if you are vulnerable
If your program:

  • Is written or depends on a program written in a language that suffers from buffer overflows AND
  • Takes input from a user AND
  • Does not sanitize it AND
  • Uses the equivalent of functions like printf(), snprintf(), and friends, or uses system services which use them, like syslog

It is highly likely that the application is vulnerable to attack.

How to protect yourself

  • Use programming languages other than C or C++.
  • Avoid the use of functions like printf() and friends which allow user input to modify the output format.
  • Validate user input to prevent format string meta characters from being used in input.
  • If relying upon operating systems and utilities written in C or C++, ensure that they use the principle of least privilege, deploy on systems with no execute stacks (not a complete protection), and keep the system up to date with patches.

Unicode Overflow
Unicode exploits are a bit more difficult to do than typical buffer overflows as demonstrated in Anley's 2002 paper, but it is wrong to assume that by using Unicode, you are protected against buffer overflows. Examples of Unicode overflows include Code Red, which is a devastating Trojan.

How to determine if you are vulnerable
If your program:

  • Is written or depends on a program written in a language that suffers from buffer overflows AND
  • Takes Unicode input from a user AND
  • Does not sanitize it AND
  • Uses heap or stack allocated variables without any canary values

It is likely that the application is vulnerable to attack.

How to protect yourself

  • Keep up with the latest bug reports for your web and application server products and other products in your Internet infrastructure. Apply the latest patches to these products.
  • Periodically scan your website with one or more of the commonly available scanners that look for buffer overflow flaws in your server products and your custom web applications.
  • Review your code for Unicode exploits.

For your custom application code, you need to review all code that accepts input from untrusted sources, and ensure that it provides appropriate size checking on all such inputs.

This should be done even for environments that are not susceptible to such attacks as overly large inputs that are uncaught may still cause denial of service or other operational problems.

Integer Overflow
When an application takes two numbers of fixed word size and perform an operation with them, the result may not fit within the same word size. For example, if two 8 bit numbers 192 and 208 are added together and stored into another 8-bit byte, the result will simply not fit into the 8 bit result:

 % 1100 0000
+ % 1101 0000
= % 0001 1001 0000

The top most half word is thrown away, and the remnant is not a valid result. This can be a problem for any language. For example, many hexadecimal conversions will "successfully" convert %M0 to 192. Other areas of concern include array indices and implicit short math.

How to determine if you are vulnerable

  • Look for signed integers, particularly bytes and shorts
  • Are there cases where these values are used as array indices after performing an arithmetic operation such as + - * / or modulo?
  • Does the code cope with negative or zero indices?

How to protect yourself

  • .NET: Use David LeBlanc's SafeInt<> C++ class or a similar construct.
  • If your compiler supports it, change the default for integers to be unsigned unless otherwise explicitly stated. Use unsigned whenever you mean it.
  • Use range checking if your language or framework supports it.
  • Be careful when using arithmetic operations near small values, particularly if underflow or overflow, signed or other errors may creep in.

Further reading

Dig deeper on Building security into the SDLC (Software development life cycle)

Pro+

Features

Enjoy the benefits of Pro+ membership, learn more and join.

0 comments

Oldest 

Forgot Password?

No problem! Submit your e-mail address below. We'll send you an email containing your password.

Your password has been sent to:

-ADS BY GOOGLE

SearchSOA

TheServerSide

SearchCloudApplications

SearchAWS

SearchBusinessAnalytics

SearchFinancialApplications

SearchHealthIT

Close