skip to Main Content

enter image description hereI’m encountering an issue with whereFullText in Laravel. Here’s my code:

$search_key = $args['q'] ?? $args['search_key'] ?? NULL;
$builder->when($search_key, function (Builder $builder, $search_key) {
    $builder->whereFullText(self::fullTextColumns(), $search_key . self::WILDCARD, [
        'mode' => 'boolean', // [ natural, natural language, query expansion, boolean ]
    ]);
});

When a client sends a search_key that contains malicious payload like "asd--", the rest of my SQL query gets commented out. This vulnerability leaves it open to SQL injection. Is there any way to handle this issue?
this problem only happens when mode is in "boolean". other modes work as expected!!

2

Answers


  1. Chosen as BEST ANSWER

    i have also write a sanitizer without using regex:

    protected static function sanitizeKeyword($keyword): string
    {
        // Define an array of special characters to be handled
    
        // Split the input keyword into an array of individual words
        $keywordArray = array_filter(explode(' ', $keyword), function ($word) {
            return strlen($word) >= 3;
        });
    
        // Function to remove leading and trailing special characters from a keyword
        $trimSpecialChars = function ($word) {
            $specialChar = ['*', '+', '-', ' ', '(', ')', '~', '@', '%', '<', '>'];
            $word        = ltrim($word, implode('', $specialChar));
    
            return rtrim($word, implode('', $specialChar));
        };
    
        // Sanitize each keyword and filter out any empty results after trimming
        $sanitizedKeywords = array_filter(array_map($trimSpecialChars, $keywordArray));
    
        // Join the sanitized keywords into a single string with ' ' . self::AND separator
        $finalString = implode(' ' . self::AND, $sanitizedKeywords);
    
        // Prepend self::AND to the final string if it is not empty
        if (! empty($finalString)) {
            $finalString = $finalString . self::WILDCARD;
        }
    
        return $finalString;
    }
    

  2. MySql’s full text search has several characters as operators, so +, -, and * have special meanings. I’d suggest sanitizing the string before passing it along the query. I strip out everything except alphanumeric characters and replace it with spaces, then tweak it a bit more to remove extra spaces:

    $q = preg_replace('/[^a-zd]+/i', ' ', $q);
    $q = preg_replace('/s+/', ' ', $q);
    $q = trim($q);
    

    If you want to make sure every word is present, replace the spaces with space and plus:

    $q = '+' . str_replace(' ', ' +', $q);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search