Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible ReDoS #6

Open
elcreator opened this issue Jun 2, 2024 · 1 comment
Open

Possible ReDoS #6

elcreator opened this issue Jun 2, 2024 · 1 comment
Assignees
Labels
enhancement New feature or request

Comments

@elcreator
Copy link
Sponsor

https://github.com/phalcon/bridge-swoole/blob/master/src/Request.php#L180
should be like

#(\\w+)=(["\'])?([^"\', ]+)(\\2)?#

to mitigate so called "catastrophic backtracking" https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS when provided input like "a=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
(or optionally even stricter if it's possible to replace "+" with reasonable max length)

@Jeckerson Jeckerson self-assigned this Jun 2, 2024
@Jeckerson Jeckerson added the enhancement New feature or request label Jun 2, 2024
@elcreator
Copy link
Sponsor Author

Looks like it's really minor one for php8.2, with 4 times performance difference between regexes for 1MB payload, i.e. nothing catastrophic but worth checking. I just generated the next code to check:

function generate_long_input($length) {
    // Generate a long string with repetitive patterns that could cause backtracking
    $base = 'key="';
    $middle = 'a';
    $repeated = str_repeat($middle, $length);
    return $base . $repeated; // No closing quote to simulate the problematic scenario
}

$patternOriginal = "#(\\w+)=(['\"]?)([^'\" ,]+)\\2#"; // Original regex with mandatory backreference
$patternRevised =  '#(\\w+)=(["\'])?([^"\', ]+)(\\2)?#'; // Revised regex with optional backreference

// Generate a long input string
$input = generate_long_input(1000000);  // You can adjust the length to see the difference

// Measure execution time for the revised pattern
$start_time = microtime(true);
preg_match_all($patternRevised, $input, $matchesRevised);
$end_time = microtime(true);
$timeRevised = $end_time - $start_time;

// Measure execution time for the original pattern
$start_time = microtime(true);
preg_match_all($patternOriginal, $input, $matchesOriginal);
$end_time = microtime(true);
$timeOriginal = $end_time - $start_time;

// Output the results
echo "Execution time for the original pattern: " . $timeOriginal . " seconds\n";
echo "Execution time for the revised pattern: " . $timeRevised . " seconds\n";

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants