Summary:
I have setup a basic WAF with mod-security and the OWASP coreruleset 3.3.2. When using the WAF I see lots of warnings in modsec_audit.log regarding the CONNECT method, which trigger crs rule 920100:
Message: Warning. Match of "rx ^(?i:(?:[a-z]{3,10}\s+(?:\w{3,7}?://[\w\-\./](?::\d+)?)?/[^?#](?:\?[^#\s])?(?:#[\S])?|connect (?:\d{1,3}\.){3}\d{1,3}\.?(?::\d+)?|options \)\s+[\w\./]+|get /[^?#](?:\?[^#\s])?(?:#[\S])?)$" against "REQUEST_LINE" required. [file "/etc/httpd/modsecurity.d/owasp-modsecurity-crs/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf"] [line "63"] [id "920100"] [msg "Invalid HTTP Request Line"] [data "CONNECT oneofmy.longer.hostname.here.abcde.com:443 HTTP/1.1"] [severity "WARNING"] [ver "OWASP_CRS/3.3.2"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-protocol"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/210/272"]
Details regarding setup:
I set up the WAF with mod_security 2.9.2 and httpd. I used the crs-setup.conf.example
provided by crs and only modified these two settings regarding threshhold and allowing the CONNECT http method. (CONNECT method is used in our setup for proxy purposes).
SecAction \
"id:900110,\
phase:1,\
nolog,\
pass,\
t:none,\
setvar:tx.inbound_anomaly_score_threshold=5,\
setvar:tx.outbound_anomaly_score_threshold=4"
SecAction \
"id:900200,\
phase:1,\
nolog,\
pass,\
t:none,\
setvar:'tx.allowed_methods=GET HEAD POST OPTIONS CONNECT'"
What I have tried so far:
CONNECT oneofmy.longer.hostname.here.abcde.com:443 HTTP/1.1
Looking at the part of the regular expression for rule 920100 that deals with the CONNECT
method:
connect (?:\d{1,3}\.){3}\d{1,3}\.?(?::\d+)?
we can see that it's looking for an IPv4 address. For example, it would match on (and hence not raise an alert for) a request line like the following:
CONNECT 1.2.3.4:80 HTTP/1.1
As you say, the RFC seems to allow for domain names to be used with the CONNECT
method, however, rule 920100 is not currently written to allow for this. This seems to be the cause of your issue.
With further investigation and testing, the rule can probably be expanded in a future CRS release to allow for domain names in CONNECT
requests.
To address this issue right now, you can add a rule exclusion to your Apache configuration. There are two ways you can do this:
#
# -- CRS Rule Exclusion: 920100 - Invalid HTTP Request Line
#
# Turn off rule due to issues with CONNECT requests
#
SecRuleRemoveById 920100
As a configure time rule exclusion, this should be placed after the inclusion of the Core Rule Set in your Apache configuration (because the rule that's being removed must be added/included in the first place before it can then be removed!).
#
# -- CRS Rule Exclusion: 920100 - Invalid HTTP Request Line
#
# Turn off rule for CONNECT requests, which cause issues
#
SecRule REQUEST_METHOD "@streq CONNECT" \
"id:1000,\
phase:1,\
pass,\
nolog,\
ctl:ruleRemoveById=920100"
As a runtime time rule exclusion, this should be placed before the inclusion of the CRS in your Apache configuration (because the rule that's being modified must be modified before it fires off during execution).
I can't find any mention of anyone else using ModSecurity with the CRS in this way, i.e. fielding CONNECT
requests. The CRS rules aren't written to accommodate having a domain name in the request line, so you may find that you run into further false positives as a result. You would need to deal with those in a similar way to that described above.
(You can find an excellent tutorial on the subject of writing rule exclusions here: https://www.netnea.com/cms/apache-tutorial-8_handling-false-positives-modsecurity-core-rule-set/).
Hopefully this helps.