I have Ubuntu 18.10 with apache2
, libapache2-mod-security2
, modsecurity-crs
packages with their default configuration except for enabling ModSecurity debug logging and copying modsecurity.conf-recommended
and adding SecRuleEngine On
.
I added a new SecRule
to a separate file in /etc/modsecurity/
Content of /etc/modsecurity/sf4-modsec.conf
is only one line:
SecRule RESPONSE_BODY "@rx <script" id:1000137,phase:4,deny,log,status:403
I can confirm that this rule is being loaded as it appears in debug logs with phase:1
:
[02/May/2019:20:48:33 +0200] [localhost/sid#7f8e0d51a5c8][rid#7f8e108d20a0][/_profiler/empty/search/results][4] Recipe: Invoking rule 7f8e0d40d138; [file "/etc/modsecurity/sf4-modsec.conf"] [line "1"] [id "1000137"].
[02/May/2019:20:48:33 +0200] [localhost/sid#7f8e0d51a5c8][rid#7f8e108d20a0][/_profiler/empty/search/results][5] Rule 7f8e0d40d138: SecRule "RESPONSE_BODY" "@rx <script>" "phase:1,auditlog,id:1000137,deny,log,status:403"
[02/May/2019:20:48:33 +0200] [localhost/sid#7f8e0d51a5c8][rid#7f8e108d20a0][/_profiler/empty/search/results][4] Rule returned 0.
[02/May/2019:20:48:33 +0200] [localhost/sid#7f8e0d51a5c8][rid#7f8e108d20a0][/_profiler/empty/search/results][9] No match, not chained -> mode NEXT_RULE.
[02/May/2019:20:48:33 +0200] [localhost/sid#7f8e0d51a5c8][rid#7f8e108d20a0][/_profiler/empty/search/results][4] Recipe: Invoking rule 7f8e0d40f5a0; [file "/etc/modsecurity/crs/crs-setup.conf"] [line "845"] [id "900990"].
However, it doesn’t appear in the logs if specified with phase:4
(I couldn’t find a line with 1000137
in it.)
I would expect this rule to block every page with <script>
inside it’s HTML, but it doesn’t, despite the <script>
tag 100% being in the response.
However, the installed rules from OWASP CRS set seem to work flawlessly.
My response body handling configuration:
SecResponseBodyAccess On
SecResponseBodyMimeType text/plain text/html text/xml
SecResponseBodyLimit 524288
SecResponseBodyLimitAction Reject
I tried restarting Apache by sudo service apache2 restart
several times.
I tried disabling all OWASP CRS rules and it still didn’t help.
Here’s my debug log with phase 4: https://pastebin.com/8aXk8hL0 (it’s pretty short)
2
Answers
I've spent nights trying to find out why this didn't work.
The reason is technical limitation of ModSecurity. You can see the issue here: https://github.com/SpiderLabs/ModSecurity/issues/1658
If you're using
mod_rewrite
together with apache, it is impossible to apply phase:3 or phase:4 rules and the rules from the given phases don't get executed at all.Your rules is a phase 1 rule, it needs to be a phase 4 rule to look at response bodies.
The phases are as follows:
So a phase 1 rule only has access to the Request Headers and is processed before the request body is processed by Apache, and before the request is actioned by Apache and the Response is created.
However, even if you move this to a phase 4 rule, other rules may stop this phase being run. For example OWASP CRS v2 has an
optional_rules/modsecurity_crs_10_ignore_static.conf file
with the following rule:Which runs in phase 2, and says any files ending in .html (and also .js and .css but probably less relevant here) are passed (so skip the rest of phase 2, and also phase 3 and phase 4 – phase 5 is a special phase that is always run). This would mean your phase 4 rule is not run for .html files.
Rules like these are used for performance reasons as those files, if not dynamically generated, are less risky and so no need to run the full set of rules on them.
If you really, really want to run phase 4 rules then you need to turn this rule off, either by 1) not including that file or 2) by explicitly excluding that rule with below config:
But then you may want to add another rule so this still works for css and js files.
And on that note scanning outgoing bodies is expensive. Typically incoming HTTP requests are small (unless you are an upload site) but outgoing requests will often be large, hence why
SecResponseBodyAccess
is off by default. Are you sure you want to do this? Not sure what you are trying to achieve but there may be better ways to achieve your goal (e.g. with Content Security Policy).