[regex_redos] Regular Expression Denial of Service (ReDoS)
What this check looks for
This plugin checks regex usage in directives like:
location ~ ...if ($var ~ ...)rewrite ...
It warns about patterns that may cause catastrophic backtracking. This issue is also known as ReDoS.
Why this is a problem
PCRE-style regex engines can take exponential time on certain inputs when the pattern is ambiguous (nested groups, overlapping alternations, repeated wildcards). With user-controlled input (URI, headers), a single request can burn a lot of CPU in one worker, allowing it to effectively be killed.
Bad configuration
# Classic catastrophic backtracking style pattern
location ~ (a+)+$ {
return 200 "ok";
}
A long string of a characters followed by a mismatch can keep the engine backtracking for an extremely long time (many seconds per request).
Better configuration
Anchor the pattern, simplify it, and avoid nested quantifiers:
# Anchored, linear-time for simple inputs
location ~ ^a+$ {
return 200 "ok";
}
General approaches:
- use
^and$anchors whenever possible, - avoid nested
(...)+or(.*)+constructs, - keep alternations unambiguous,
- constrain input length before matching expensive patterns.
- use recheck against any regex patterns used to check for vulnerable expressions.
Configuration
This plugin is opt-in. It does not run unless you point it at a ReDoS checking service.
url
You can use the url option to configure the ReDoS checking server. The plugin will POST regex patterns to this endpoint and expects a response compatible with the recheck JSON format (for example, MegaManSec/recheck-http-api).
By default, this value is empty, which means the plugin skips.
CLI
# Send regex patterns to this service for evaluation
gixy --regex-redos-url "http://127.0.0.1:8080/"
Config
[regex_redos]
; URL of a compatible ReDoS checking server
url = http://127.0.0.1:8080/
Additional notes
Severity
This plugin reports different severities depending on the result of the external checker:
- MEDIUM, if the external checker reports the expression is vulnerable to ReDoS.
- UNSPECIFIED, if the plugin cannot evaluate the expression for one reason or another (server failure, network failure, invalid JSON, etc.)
When this check is skipped
This plugin is intentionally "opt-in" and will silently skip in these cases:
- The Python
requestsdependency is not available. - You did not configure a checker URL (the
--regex-redos-url/ pluginurloption).
The plugin is opt-in because it requires calling to an external service. You can download an run that service, titled recheck-http-api.
More information
For more information about ReDoS vulnerabilities in nginx, see this post.