Describing of bug
In v2, if a SecRule contains a sequence of \\ (double backslash), the parser interprets it as a single \ (backslash) character. This is because the reading of config file is the Apache job. The process chain in v2 is something like this: ap_getword_conf (declared in httpd.h), it is called from ap_build_config (declared in http_config.h), and the root of this chain is ap_read_config (also in http_config.h) - but as I saw there is copy of the body of ap_getword_conf() function in modsec source...
This function strips the double \\, and the parser got a single \ character. For example, if the rule looks like this:
SecRule ARGS "@rx \\\\u006C" ...
then the pattern will only \u006C in stage of parsing of rule, and will \u006C in stage of building regex. Then if an argument contains \u006C, then it matches.
ModSecurity3 has an own parser, and it keeps the patterns as is, doesn't strip them, so the \\\\u006C will \\\\u006C, and the regex will got \\u006C - so the mentioned argument will not match.
The essence of this issue (and the contradictory behavior), that if the SecRule is not in the included configuration file, but is it in the webserver config file (eg in virtual context:
modsecurity_rules '
SecRuleEngine On
....
SecRule ARGS "@rx \\\\u006C"...
)
then it works. So, that's a bit confused: I can't pass the same rule as same syntax with both avaliable method...
How to reproduce
Set up the Nginx with ModSecurity and OWASP CRS. Send a curl request:
curl -v 'http://localhost/?var=%22in%20\\u0076\\u0061l\\u0075e\\u004F\\u0066%3d
It will passed, ModSecurity 3 doesn't catch it.
Expected behavior
It would be expected that ModSecurity catches this curl request above, like mod_security2.
Affected versions
This issue affects all ModSecurity3 versions.
Rule Set
The good real example is the OWASP CRS, rule 941330:
https://github.com/SpiderLabs/owasp-modsecurity-crs/blob/00077e1401f53c32fc7c170d059f3003cd154f52/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf#L854
Describing of bug
In v2, if a SecRule contains a sequence of
\\(double backslash), the parser interprets it as a single\(backslash) character. This is because the reading of config file is the Apache job. The process chain in v2 is something like this:ap_getword_conf(declared in httpd.h), it is called fromap_build_config(declared in http_config.h), and the root of this chain isap_read_config(also in http_config.h) - but as I saw there is copy of the body of ap_getword_conf() function in modsec source...This function strips the double
\\, and the parser got a single\character. For example, if the rule looks like this:SecRule ARGS "@rx \\\\u006C" ...then the pattern will only \u006C in stage of parsing of rule, and will \u006C in stage of building regex. Then if an argument contains \u006C, then it matches.
ModSecurity3 has an own parser, and it keeps the patterns as is, doesn't strip them, so the
\\\\u006Cwill\\\\u006C, and the regex will got\\u006C- so the mentioned argument will not match.The essence of this issue (and the contradictory behavior), that if the SecRule is not in the included configuration file, but is it in the webserver config file (eg in virtual context:
)
then it works. So, that's a bit confused: I can't pass the same rule as same syntax with both avaliable method...
How to reproduce
Set up the Nginx with ModSecurity and OWASP CRS. Send a curl request:
curl -v 'http://localhost/?var=%22in%20\\u0076\\u0061l\\u0075e\\u004F\\u0066%3dIt will passed, ModSecurity 3 doesn't catch it.
Expected behavior
It would be expected that ModSecurity catches this curl request above, like mod_security2.
Affected versions
This issue affects all ModSecurity3 versions.
Rule Set
The good real example is the OWASP CRS, rule 941330:
https://github.com/SpiderLabs/owasp-modsecurity-crs/blob/00077e1401f53c32fc7c170d059f3003cd154f52/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf#L854