CWE-787: Out-of-bounds Write
Learn about CWE-787 (Out-of-bounds Write), its security impact, exploitation methods, and prevention guidelines.
What is Out-of-bounds Write?
• Overview: Out-of-bounds Write occurs when a program writes data outside the allocated boundaries of a buffer, either beyond its end or before its start. This typically happens due to miscalculations or inadequate boundary checks in the code, leading to overwriting of adjacent memory locations.
• Exploitation Methods:
- Attackers exploit this vulnerability by crafting inputs that cause the program to write outside the buffer's limits, potentially altering the program's execution flow.
- Common attack patterns include buffer overflow attacks, where carefully crafted data can overwrite return pointers, function pointers, or other critical data structures.
• Security Impact:
- Direct consequences include application crashes, data corruption, and system instability.
- Potential cascading effects involve execution of arbitrary code, privilege escalation, and unauthorized access to sensitive data.
- Business impact can range from data breaches and loss of customer trust to financial losses due to service interruptions or data loss.
• Prevention Guidelines:
- Specific code-level fixes include implementing proper bounds checking and using safe functions that limit the amount of data written to buffers.
- Security best practices involve adopting secure coding standards, performing regular code reviews, and conducting static and dynamic analysis to identify vulnerabilities.
- Recommended tools and frameworks include using compiler options like stack canaries, and employing memory-safe languages or libraries that manage buffer sizes automatically.
Technical Details
Likelihood of Exploit:
Affected Languages: C, C++, Assembly
Affected Technologies: ICS/OT
Vulnerable Code Example
// Vulnerable code demonstrating an out-of-bounds write issue
#include <stdio.h>
#include <string.h>
void copy_input(const char *input) {
char buffer[10]; // Buffer is only 10 bytes long
// Vulnerability: This line does not check if the input length exceeds buffer size
strcpy(buffer, input); // Out-of-bounds write occurs if input is longer than 9 characters
// 'strcpy' will continue to write past the buffer's allocated memory, causing undefined behavior
printf("Buffer contains: %s\n", buffer);
}
int main() {
const char *user_input = "This input is definitely too long for the buffer!";
copy_input(user_input);
return 0;
}
How to fix Out-of-bounds Write?
To fix this vulnerability, we should ensure that any data copied into a buffer fits within the allocated space. This can be achieved by using safer functions such as strncpy
or snprintf
, which allow us to specify the maximum number of bytes to copy. It's also important to ensure that the buffer is null-terminated if necessary.
Specifically, the fixes include:
- Using
strncpy
to limit the copied data size to one less than the buffer size, ensuring space for a null terminator. - Explicitly null-terminating the buffer after using
strncpy
to prevent any accidental overflows.
Fixed Code Example
// Fixed code with proper bounds checking
#include <stdio.h>
#include <string.h>
void copy_input(const char *input) {
char buffer[10]; // Buffer is 10 bytes long
// Fix: Use 'strncpy' to limit the number of characters copied to avoid overflow
strncpy(buffer, input, sizeof(buffer) - 1);
// Ensure null-termination of the buffer
buffer[sizeof(buffer) - 1] = '\0'; // Explicitly null-terminate the string
printf("Buffer contains: %s\n", buffer);
}
int main() {
const char *user_input = "This input is definitely too long for the buffer!";
copy_input(user_input);
return 0;
}
In the fixed code, strncpy
is used to ensure that only up to sizeof(buffer) - 1
characters are copied to the buffer
, leaving room for the null terminator. We manually set the last character in the buffer to \0
to ensure it is properly null-terminated, preventing any overflow and ensuring the program behaves as expected.