CWE 787 -Out of Bounds Write

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

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

  • 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 787

Out of Bounds Write

This Vulnerability occurs when a program writes data outside of the intended buffer or memory location.

Impact

  • Buffer Overflow

  • Code/Command Execution

  • DoS/Data Corruption

  • Privilege Escalation/Crash

Example with Code Explanation:

C++

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

Vulnerable Code

#include <iostream>
#include <cstring>

int main(int argc, char* argv[]) {
    char buffer[10];
    strcpy(buffer, argv[1]);
    std::cout << buffer << std::endl;
    return 0;
}
  • This code is vulnerable to buffer overflow because the strcpy function is being used to copy user input from argv[1] into the fixed-size buffer array. Also, The strcpy function doesn't check the length of the input being copied, so if the input is longer than 10 characters, it will overwrite adjacent memory, potentially causing a crash or allowing an attacker to execute arbitrary code.

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

    • Check the length of the input before copying it, and reject input that is too large.

    • Use strlcpy() instead of strcpy() which is similar to strncpy() but ensure NULL termination of the string.

    • Use strncpy() instead of strcpy() and pass the size of the buffer as the maximum number of characters to copy.

    • Use a library function specifically designed to safely copy strings, such as strscpy().

    • Use a library that has built-in bounds checking, such as the C++ string class.

Mitigated Code

#include <iostream>
#include <cstring>

int main(int argc, char* argv[]) {
    char buffer[10];
    size_t input_length = strlen(argv[1]);
    if (input_length >= sizeof(buffer)) {
        std::cout << "Input too long!" << std::endl;
        return -1;
    }
    strlcpy(buffer, argv[1], sizeof(buffer));
    std::cout << buffer << std::endl;
    return 0;
}
  • The mitigated code does the following:

    • First, it calculates the length of the input string using strlen(argv[1]) and stores it in the input_length variable.

    • Next, it checks whether the input string is longer than the size of the buffer using an if statement. If it is, the program prints an error message and exits with a non-zero status code. This prevents a buffer overflow from occurring if the input string is too large.

    • If the input string is shorter than the buffer, it calls strlcpy function with three arguments: the destination buffer, the source string, and the size of the buffer. This function copies at most size-1 bytes from the source string to the destination buffer, and then it adds a null-terminating byte. It also returns the total length of the string it tried to create, so if the returned value is greater or equal to the size of the buffer that means the buffer is truncated and it will not overflow.

    • Finally, it prints the contents of the buffer using std::cout << buffer << std::endl; and the program exits with a zero status code.

💡 Another way is to use **`strncat`** or **`strlcat`** , which will append the input string to the buffer, and ensure that the buffer is null-terminated.

Java

Vulnerable Code

public class OutOfBoundsWrite {
    public static void main(String[] args) {
        // Allocate an array of 10 integers
        int[] array = new int[10];

        // Read an index and a value from the command line
        int index = Integer.parseInt(args[0]);
        int value = Integer.parseInt(args[1]);

        // Write the value to the specified index of the array
        array[index] = value;
    }
}
  • The code above is vulnerable to CWE-787, due to the lack of input validation, bounds checking and insufficient input handling. The program reads index and value from command line, but it doesn't check the index is within the bounds of the array, this can cause an ArrayIndexOutOfBoundsException. Also, the code uses parseInt method to convert the arguments which doesn't perform any input validation and can throw an exception. In addition, the program doesn't check the number of arguments and doesn't initialize the array with specific values which can lead to sensitive data leakage.

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

    • Perform input validation to ensure that the index and value passed as command line arguments are integers and within the expected range.

    • Check that the index is within the bounds of the array before using it to access an element in the array.

    • Sanitize the inputs. Ensure that the inputs are only coming from a valid source, and in a valid format

Mitigated Code

public class OutOfBoundsWrite {
    public static void main(String[] args) {
        if(args.length < 2) {
            System.out.println("Please provide two arguments, index and value");
            return;
        }

        int[] array = new int[10];

        int index;
        int value;
        try {
            index = Integer.parseInt(args[0]);
            value = Integer.parseInt(args[1]);
            // Check if value is too large for array
            if (value >= int.MinValue && value <= int.MaxValue) {
                if (index >= 0 && index < array.length) {
                    array[index] = value;
                } else {
                    System.out.println("Index is out of bounds");
                }
            } else {
                System.out.println("Value is too large for array");
            }
        } catch (NumberFormatException e) {
            System.out.println("Index and value should be integers");
            return;
        }
    }
}
  • The Mitigated code does the following:

    • The code takes two arguments from command line, first one is index and second one is value. It creates an array of size 10 and then it checks the following points:

    • whether the index is within the bounds of the array (index >= 0 && index < array.length)

    • whether the value is within the valid range for int (value >= int.MinValue && value <= int.MaxValue)

    • if both of the above conditions are met, it assigns the value to the specified index in the array.

  • The code also checks if the provided arguments are integers, if not, it notifies the user and exits.

  • This code has following mitigations:

    • Checking the index is within the bounds of the array

    • Checking the value is within the valid range for int

    • Checking if the provided arguments are integers

    • Checking if the two arguments are provided

.NET

Vulnerable Code

public class OutOfBoundsWrite
{
    public static void Main(string[] args)
    {
        // Allocate an array of 10 integers
        int[] array = new int[10];

        // Read an index and a value from the command line
        int index = int.Parse(args[0]);
        int value = int.Parse(args[1]);

        // Write the value to the specified index of the array
        array[index] = value;
    }
}
  • The above code is vulnerable due to:

    • The code does not perform any input validation on the index and value passed as arguments to the program.

    • The int.Parse() method is used to convert the input strings to integers, but it does not check if the input strings are valid integers or if the resulting integers are within the bounds of the array

  • The Vulnerable code can be mitigated by:

    • Add validation check to ensure that the provided index is within the bounds of the array before using it to access the array.

    • Add check to ensure that the provided value is within the valid range before using it to write to the array.

    • add check for number of input variable

    • use try catch block for number format exception for index and value

    • return error message if any of the above case not met

Mitigated Code

using System;

class OutOfBoundsWrite {
    static void Main(string[] args) {
        if(args.Length < 2) {
            Console.WriteLine("Please provide two arguments, index and value");
            return;
        }

        int[] array = new int[10];

        int index;
        int value;
        try {
            index = int.Parse(args[0]);
            value = int.Parse(args[1]);
            // Check if index is within the array bounds
            if (index >= 0 && index < array.Length) {
                // Check if value is within the valid range for int
                if (value >= int.MinValue && value <= int.MaxValue) {
                    array[index] = value;
                } else {
                    Console.WriteLine("Value is out of range");
                }
            } else {
                Console.WriteLine("Index is out of bounds");
            }
        } catch (FormatException e) {
            Console.WriteLine("Index and value should be integers");
            return;
        }
    }
}
  • The Mitigated Code does the following:

    • It checks if the number of arguments passed is less than 2 and returns an error message if that is the case.

    • It checks if the provided index is within the bounds of the array before using it.

    • It checks if the provided value is within the valid range for int before using it.

    • It uses the try-catch block to handle the exception if the arguments passed are not integers.

References

Buffer Overflow | OWASP Foundation

OWASP Code Review Guide | OWASP Foundation

Last updated

Was this helpful?