TL;DR
A buffer overflow happens when a program tries to put more data into a space (the ‘buffer’) than it can hold. This can overwrite other important parts of the computer’s memory, potentially letting attackers take control. We’ll look at how this works with a basic example and how to protect against it.
Understanding Buffer Overflows
- What is a buffer? A buffer is just an area in the computer’s memory set aside to hold data temporarily. Think of it like a container.
- What causes an overflow? It happens when you try to put more stuff into the container than it can handle. For example, if your container holds 10 items and you try to put in 15, some will spill over.
- Why is this a problem? That ‘spilling over’ can overwrite other important data or even program instructions. An attacker can deliberately cause an overflow to change how the program runs, often to execute their own malicious code.
A Simple Example (C)
Let’s look at a very basic C example:
#include <stdio.h>
#include <string.h>
int main() {
char buffer[10];
printf("Enter some text: ");
scanf("%s", buffer);
printf("You entered: %sn", buffer);
return 0;
}
In this code, buffer[10] creates a buffer that can hold 9 characters plus the null terminator. The problem is with scanf("%s", buffer). It doesn’t check how long the input text is. If you enter more than 9 characters, it will write past the end of the buffer – this is a buffer overflow.
How an Attack Works
- The Vulnerability: The
scanf("%s", buffer)function in our example has no bounds checking. - Crafting the Input: An attacker would provide input longer than 9 characters. This input is carefully designed to overwrite parts of memory, including the return address on the stack.
- Overwriting the Return Address: The return address tells the program where to go after the current function (
mainin this case) finishes. By overwriting it with a malicious address, the attacker can redirect execution to their own code. - Executing Malicious Code: When
mainreturns, instead of going back to the normal calling function, it jumps to the attacker’s code.
Protecting Against Buffer Overflows
- Use Safe Functions: Avoid functions like
scanf("%s", ...)that don’t have bounds checking. Use safer alternatives likefgets()orstrncpy(). fgets(buffer, sizeof(buffer), stdin): This reads at mostsizeof(buffer) - 1characters from the input stream (stdin in this case). It also adds a null terminator.strncpy(destination, source, n): This copies at mostncharacters fromsourcetodestination. Be careful – it doesn’t automatically add a null terminator if the source string is longer thann. You might need to manually add one.- Compiler Protections: Modern compilers offer protections like Stack Canaries and Address Space Layout Randomization (ASLR). Make sure these are enabled.
- Stack Canaries: A random value is placed on the stack before the return address. If a buffer overflow overwrites it, the program detects this and terminates.
- ASLR: Randomizes the memory addresses of key parts of the program (like libraries and the stack) making it harder for attackers to predict where their malicious code should go.
- Data Execution Prevention (DEP): Marks certain areas of memory as non-executable, preventing attackers from running code in those regions.
- Input Validation: Always check the length and format of user input before using it. Don’t trust any external data without validation.
Example with fgets
Here’s how you could fix our example using fgets:
#include <stdio.h>
#include <string.h>
int main() {
char buffer[10];
printf("Enter some text: ");
fgets(buffer, sizeof(buffer), stdin);
printf("You entered: %sn", buffer);
return 0;
}
Now, fgets will only read up to 9 characters into the buffer, preventing the overflow.

