Lack of data validation - Source Code - PHP

Lack of data validation - Source Code - PHP

Need

Implementation of robust data validation in the source code

Context

  • Usage of PHP 7.0+ for server-side scripting and web development
  • Usage of Request for making HTTP requests
  • Usage of the User dependency for user-related functionality

Description

Non compliant code

        public function userSearch(Request $request)
{
    $search = $request->input('search');
    $pattern = '/^.*'.$search.'.*$/i';

    $users = User::whereRaw("name REGEXP '".$pattern."'")->get();

    return view('users.index', ['users' => $users]);
}
        
        

The above code is a method in a Laravel controller that fetches users from a database based on a search query provided by a user. The search query is directly appended to a regular expression pattern and used in a raw SQL query without any form of validation or sanitization. This makes the application vulnerable to Regular Expression Denial of Service (ReDoS) attacks.

In a ReDoS attack, an attacker can provide a specially crafted string as the search query that takes a long time to evaluate against the regular expression. This can cause the server to use a significant amount of CPU resources, leading to a denial of service as the server becomes unresponsive.

This vulnerability is particularly dangerous because it does not require any special privileges or knowledge about the system
- any user who can send a request to the userSearch endpoint can potentially exploit it.

Steps

  • Sanitize the user input to ensure it does not contain any malicious code or harmful data.
  • Avoid using raw queries and regular expressions directly with user input to prevent Regular Expression Denial of Service (ReDoS) attacks.
  • Use parameterized queries or prepared statements to prevent SQL injection attacks.
  • Implement input validation to ensure the data is in the correct format and type before processing it.
  • Use a safer method to perform the search operation, such as using Laravel's built-in functions like 'like' or 'ilike'.
  • Consider implementing rate limiting to prevent abuse of the search functionality.

Compliant code

        public function userSearch(Request $request)
{
    $search = $request->input('search');
    $search = filter_var($search, FILTER_SANITIZE_STRING);

    if (!is_string($search)) {
        return redirect()->back()->withErrors(['search' => 'Invalid search input']);
    }

    $users = User::where('name', 'like', '%'.$search.'%')->get();

    return view('users.index', ['users' => $users]);
}
        
        

The updated code now includes a few security measures to prevent potential attacks:

1. Input Sanitization: The user's search input is sanitized using PHP's built-in filter_var() function with the FILTER_SANITIZE_STRING filter. This function will strip tags and remove or encode special characters from a string.

2. Input Validation: The sanitized input is then checked to ensure it is a string. If it is not, an error message is returned and the user is redirected back to the previous page.

3. Safe Querying: Instead of using a raw query with a regular expression, Laravel's built-in where() function is used with the 'like' operator to perform the search. This method is safer as it automatically escapes the input to prevent SQL injection attacks.

By implementing these measures, the code is now more secure against potential Regular Expression Denial of Service (ReDoS) attacks, SQL injection attacks, and other forms of malicious input.

References