Out-of-bounds read - PHP

Out-of-bounds read - PHP

Need

Prevention of out-of-bounds read vulnerabilities

Context

  • Usage of PHP for server-side scripting and web development
  • Usage of Request for making HTTP requests

Description

Non compliant code

        public function readArray(Request $request) {
    $data = $request->input('data');
    $index = $request->input('index');

    return $data[$index];
}
        
        

The above code is a simple Laravel function that reads an array from an HTTP request and returns the value at a specified index. However, this code is vulnerable to an Out-of-Bounds read, as it does not check whether the given index is within the bounds of the array.

If a user provides an index that is outside the range of the array, Laravel will attempt to access memory that is not part of the array. This can lead to unexpected behavior, including the application crashing or sensitive data being exposed.

For example, if a user sends a request with an array of 5 elements and an index of 10, the function will attempt to return the 10th element of the array. Since the array only has 5 elements, this will result in an Out-of-Bounds read.

Steps

  • First, validate the 'index' input to ensure it is a non-negative integer.
  • Then, check if the 'index' is less than the length of the 'data' array.
  • If the 'index' is not valid, return an error message or handle the error appropriately.
  • Only if the 'index' is valid, access the 'data' array at the 'index'.

Compliant code

        public function readArray(Request $request) {
    $data = $request->input('data');
    $index = $request->input('index');

    // Validate the 'index' input
    if (!is_int($index) || $index < 0) {
        return response()->json(['error' => 'Invalid index.'], 400);
    }

    // Check if the 'index' is less than the length of the 'data' array
    if ($index >= count($data)) {
        return response()->json(['error' => 'Index out of bounds.'], 400);
    }

    // Access the 'data' array at the 'index'
    return $data[$index];
}
        
        

The updated code first validates the 'index' input to ensure it is a non-negative integer. If the 'index' is not an integer or is less than 0, the function returns a JSON response with an error message and a 400 status code, indicating a bad request.

Next, the code checks if the 'index' is less than the length of the 'data' array. If the 'index' is equal to or greater than the count of the 'data' array, the function again returns a JSON response with an error message and a 400 status code.

Only if the 'index' is valid (i.e., it is a non-negative integer and less than the length of the 'data' array), the function accesses the 'data' array at the 'index' and returns the value.

This way, the code prevents an out-of-bounds read, which could potentially lead to the system reading data before or beyond the intended buffer.

References