Buffer overflow happens when a program writes beyond the bounds of an allocated memory buffer. In C and C++, unsafe string functions like strcpy and gets are the most common root cause. This guide covers vulnerable patterns, detection tools, and bounded replacements.
A buffer overflow occurs when a program writes more data into a fixed-size memory region (the buffer) than it was allocated to hold. The excess data overwrites adjacent memory — which may contain other variables, function return addresses, or heap metadata.
Depending on what is overwritten, the consequence ranges from a crash to arbitrary code execution. Stack buffer overflows (CWE-121) that overwrite return addresses are a classic exploitation primitive. Heap overflows (CWE-122) corrupt allocator metadata or adjacent objects.
| Unsafe | Safe replacement | Why |
|---|---|---|
| strcpy(dst, src) | strlcpy(dst, src, sizeof(dst)) or strncpy + explicit NUL | strcpy has no length limit |
| strcat(dst, src) | strlcat(dst, src, sizeof(dst)) | strcat has no length limit |
| sprintf(buf, fmt, ...) | snprintf(buf, sizeof(buf), fmt, ...) | sprintf can overflow buf |
| gets(buf) | fgets(buf, sizeof(buf), stdin) | gets has no bound — always unsafe |
| scanf("%s", buf) | scanf("%255s", buf) with explicit width | Unbounded %s reads forever |
| memcpy(dst, src, len) | memcpy + check len <= sizeof(dst) | len must be validated before call |
Vulnerable
void process_input(char *user_input) {
char buf[64];
// Dangerous: no length check, overwrites stack if input > 64 bytes
strcpy(buf, user_input);
}Secure
void process_input(char *user_input) {
char buf[64];
// Safe: bounded copy, guaranteed NUL termination
snprintf(buf, sizeof(buf), "%s", user_input);
}Vulnerable
char *build_query(const char *name) {
char *buf = malloc(64);
// Dangerous: name may exceed remaining buffer space
sprintf(buf, "SELECT * FROM users WHERE name='%s'", name);
return buf;
}Secure
char *build_query(const char *name) {
char *buf = malloc(256);
// Safe: snprintf limits output to buffer size
snprintf(buf, 256, "SELECT * FROM users WHERE name='%s'", name);
return buf;
}Static analysis and runtime tools complement each other for buffer overflow detection:
strcpy, gets, sprintf)-Wall -Wformat-overflow -D_FORTIFY_SOURCE=2# Semgrep: flag strcpy calls in C
rules:
- id: c-unsafe-strcpy
pattern: strcpy($DST, $SRC)
message: strcpy has no length limit — use snprintf or strlcpy (CWE-120)
severity: ERROR
languages: [c, cpp]Orbis AppSec flags unsafe C string function calls and opens automated fix pull requests replacing them with bounded alternatives like snprintf and strlcpy.
Want Orbis AppSec to find and fix buffer overflows in your GitHub repositories?
Try Orbis AppSecBrowse posts where Orbis AppSec detected and fixed buffer overflow vulnerabilities in real open-source repositories:
View all buffer overflow case studiesA buffer overflow occurs when a program writes more data to a fixed-size buffer than it can hold, overwriting adjacent memory. This can corrupt program state, crash the process, or allow attackers to execute arbitrary code.
CWE-120 (Classic Buffer Overflow). Stack-based overflows are CWE-121 and heap-based overflows are CWE-122.
Replace unsafe functions (strcpy, sprintf, gets) with bounded equivalents (strlcpy, snprintf, fgets). Always pass and check buffer sizes explicitly.
Yes. Legacy C APIs are still widely used in C++ codebases, embedded systems, and systems software. Even modern code calling C libraries is at risk if input sizes are not validated.
Yes. Semgrep and CodeQL both have rules flagging unsafe C string functions. AddressSanitizer (ASan) and Valgrind detect overflows at runtime during testing.
Stack buffer overflow (CWE-121) overwrites the function call stack, potentially corrupting return addresses. Heap buffer overflow (CWE-122) overwrites dynamically allocated memory, corrupting heap metadata or adjacent objects.