CWE 125 - Out-of-Bounds Read

Disclaimer
  • The code provided is for **educational purposes** only and should not be used in a **production environment** without proper review and testing.

  • The provided code should be regarded as **best practice**. There are also several ways to remediate the Vulnerabilities.

  • The code provided **may contain vulnerabilities** that could be exploited by attackers, and is intended to be used as a learning tool to help improve security awareness and best practices.

  • The mitigations provided are intended to address **specific vulnerabilities** in the code, but may not be effective against all potential attack vectors or scenarios.

  • The code provided is not **guaranteed to be secure or free** from all vulnerabilities, and should be reviewed and tested thoroughly before being used in a production environment.

  • The code provided is **not a substitute for professional security** advice or guidance, and users should consult with a qualified security professional before implementing any security measures.

  • The authors and contributors of the code provided **cannot be held responsible** for any damages or losses resulting from the use of this code.

  • The code provided is provided "as is" without any warranties, express or implied, including but not limited to the implied warranties of merchantability and fitness for a particular purpose.

  • We do not have any sponsors or financial interests in any specific products or services, and the information provided is based solely on our own knowledge and experience.

  • The vulnerable and mitigated code samples provided on our platform are generated with the help of AI and sourced from the internet. We have made every effort to ensure that the code is accurate and up-to-date, but we cannot guarantee its correctness or completeness. If you notice that any of the code samples belong to you and you wish for it to be removed, please contact us and we will take appropriate action. We also apologize for any inconvenience caused and are committed to giving appropriate credit to the respective authors.

About CWE ID 125

Out-of-Bounds Read

This Vulnerability occurs when a program reads data past the end or before the beginning of a buffer, which can result in reading unintended or sensitive information, or even cause the program to crash.

Impact

  • Privilege Escalation

  • Data Corruption or Manipulation

  • Denial of Service (DoS)

Example with Code Explanation

C

  • Let us consider an example case and understand the CWE 125 with context of Vulnerable code and Mitigated code.

#include <stdio.h>
#include <string.h>

void vulnerable_function(char *input_string) {
    char buffer[10];
    strcpy(buffer, input_string); // potential out-of-bounds read vulnerability
    printf("%s\n", buffer);
}

int main() {
    char input[20] = "This is a test";
    vulnerable_function(input);
    return 0;
}
  • The vulnerable_function function takes a string input and copies it to a buffer with a fixed size of 10 characters using the strcpy function. If the input string is longer than 10 characters, strcpy will write past the end of the buffer, leading to an out-of-bounds read vulnerability. The main function passes a string input of 20 characters to the vulnerable_function, which may cause it to read beyond the end of the buffer, potentially leading to unexpected behavior or security issues.

  • Some of the ways the Vulnerable code can be mitigated is:

    • Ensure that the input length is checked before copying the input to the buffer to avoid writing beyond the end of the buffer.

    • Use safer string functions such as strncpy or snprintf that limit the number of characters copied and prevent buffer overflows.

    • Use compiler flags such as -fstack-protector to enable stack canaries, which can help detect buffer overflows at runtime.

    • Use a buffer size that is large enough to accommodate the maximum expected input size, or dynamically allocate memory to store the input.

Mitigated Code

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAX_INPUT_LENGTH 100

void safer_function(const char *input_string) {
    char *buffer = (char *) malloc(MAX_INPUT_LENGTH + 1); // dynamically allocate buffer
    if (buffer == NULL) {
        printf("Error: Could not allocate memory for buffer.\n");
        exit(1);
    }
    strncpy(buffer, input_string, MAX_INPUT_LENGTH); // use strncpy to limit the number of characters copied
    buffer[MAX_INPUT_LENGTH] = '\0'; // add null terminator to the end of the string
    printf("%s\n", buffer);
    free(buffer); // free dynamically allocated memory
}

int main() {
    safer_function("Hello, world!");
    return 0;
}
  • The Mitigated code does the following:

    • The buffer size is dynamically allocated to a maximum length of MAX_INPUT_LENGTH characters, which can accommodate all expected inputs without overflowing the buffer.

    • The strncpy function is used to limit the number of characters copied to the buffer, preventing overflows and ensuring that the null terminator is included.

    • A null terminator is added to the end of the string to ensure that it is properly terminated, preventing out-of-bounds reads of uninitialized memory.

    • After the use of the buffer, the dynamically allocated memory is freed, preventing memory leaks and ensuring that the buffer is not used after it has been freed.

C++

Vulnerable Code

#include <iostream>
#include <cstring>

void vulnerable_function(char *input_string) {
    char buffer[10];
    std::strcpy(buffer, input_string); // potential out-of-bounds read vulnerability
    std::cout << buffer << std::endl;
}

int main() {
    char input[20] = "This is a test";
    vulnerable_function(input);
    return 0;
}
  • In this vulnerable code, the vulnerable_function function takes a string input and copies it to a buffer with a fixed size of 10 characters using the strcpy function. If the input string is longer than 10 characters, strcpy will write past the end of the buffer, leading to an out-of-bounds read vulnerability.

  • The main function passes a string input of 20 characters to the vulnerable_function, which may cause it to read beyond the end of the buffer, potentially leading to unexpected behavior or security issues.

  • Some of the ways the Vulnerable code can be mitigated is:

    • Ensure that the input length is checked before copying the input to the buffer to avoid writing beyond the end of the buffer.

    • Use a buffer size that is large enough to accommodate the maximum expected input size, or dynamically allocate memory to store the input.

    • Use safer string functions such as strncpy or snprintf that limit the number of characters copied and prevent buffer overflows.

    • Use C++ standard library classes like std::string instead of C-style strings and character arrays, which have built-in boundary checking and can help prevent buffer overflows.

Mitigated Code

#include <iostream>
#include <string>

void safe_function(const std::string& input_string) {
    const size_t MAX_INPUT_LENGTH = 10;
    char buffer[MAX_INPUT_LENGTH + 1] = {0}; // allocate memory for buffer and initialize it to 0
    const size_t copy_len = std::min(input_string.length(), MAX_INPUT_LENGTH); // ensure that we don't copy more than MAX_INPUT_LENGTH characters
    size_t result = snprintf(buffer, MAX_INPUT_LENGTH + 1, "%s", input_string.substr(0, copy_len).c_str()); // use snprintf to copy input_string into buffer and ensure null termination
    if (result > MAX_INPUT_LENGTH) {
        std::cerr << "Error: Input string too long!" << std::endl;
        return;
    }
    std::cout << buffer << std::endl;
}

int main() {
    std::string input = "This is a test";
    safe_function(input);
    return 0;
}
  • The Mitigated code does the following:

    • The safe_function() function uses snprintf() to copy the input string into the buffer, which ensures that the copied string is null-terminated and will not write beyond the buffer's size.

    • The function checks if the return value of snprintf() is greater than MAX_INPUT_LENGTH. If it is, then it prints an error message and returns immediately, preventing any further code execution that might use the buffer.

Java

Vulnerable Code

public class OutOfBoundsReadExample {

    public static void main(String[] args) {
        int[] numbers = {1, 2, 3, 4, 5};
        int index = 5; // This index is out of bounds

        int result = numbers[index]; // Accessing an array element out of bounds

        System.out.println(result);
    }
}
  • We have an array of integers called numbers that has five elements. We then attempt to access an element of the array using an index of 5. Since the array only has five elements, the index of 5 is out of bounds, and attempting to access this element will result in an out-of-bounds read.

  • Some of the ways the vulnerability can be remediated is:

    • Use defensive programming techniques, such as input validation and error checking, to catch out-of-bounds read errors before they occur.

    • Always ensure that array indices used to access array elements are within the bounds of the array.

    • Use Java's built-in bounds checking mechanism to help prevent out-of-bounds read vulnerabilities.

Mitigated Code

public class MitigatedOutOfBoundsReadExample {

    public static void main(String[] args) {
        int[] numbers = {1, 2, 3, 4, 5};
        int index = 5;

        if (isValidIndex(index, numbers)) { // Check if the index is within bounds
            int result = numbers[index];
            System.out.println(result);
        } else {
            System.out.println("Index is out of bounds.");
        }
    }

    public static boolean isValidIndex(int index, int[] array) {
        return index >= 0 && index < array.length;
    }
}
  • The Mitigated code does the following:

    • We've added a method called isValidIndex() that checks if the given index is within the bounds of the given array.

    • In the main method, we use this isValidIndex() method to check if the index is within bounds before attempting to access the corresponding array element.

    • If the index is out of bounds, we print an error message instead of attempting to access the array element.

References

Last updated

Was this helpful?