0

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)

Riki137
  • 2,076
  • 2
  • 23
  • 26

2 Answers2

0

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:

  1. Request Headers
  2. Request Body
  3. Response Headers
  4. Response Body
  5. Logging

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:

# HTML
SecRule REQUEST_FILENAME "\.(?:(?:cs|j)s|html?)$"  "phase:2,t:none,t:lowercase,setvar:tx.text_file_extension=1,allow:phase,nolog,id:'999005',severity:'6'"

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:

SecRuleRemoveById 999005

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).

Barry Pollard
  • 40,655
  • 7
  • 76
  • 92
  • Thank you, i've tried that, but it didn't resolve the problem for me. I edited the answer accordingly. – Riki137 May 03 '19 at 08:37
  • Can you also update the debug logs? I suspect it isn't being called any more for static content due to CRS rules (e.g. those in modsecurity_crs_10_ignore_static.conf) explicitly allowing them in phase 2 (so they skip phases 3 and 4) for performance reasons. – Barry Pollard May 03 '19 at 08:54
  • This sounds very likely as the rule's id doesn't appear in debug logs after changing the phase to 4. Could you please update your answer as to how to stop this from happening? I updated my question. Thank you very, very much. – Riki137 May 03 '19 at 12:51
  • Updated my answer – Barry Pollard May 03 '19 at 16:26
  • I've just tried disabling all OWASP CRS rules, and the rule still appeared in debug log only in phase 1 and not in phase 4. The phase 4 doesn't seem to start. I'll update my question. Here's my debug log: https://pastebin.com/8aXk8hL0 – Riki137 May 03 '19 at 18:22
  • Also my intent is to make OWASP CRS rules using Response Body. The ` – Riki137 May 03 '19 at 18:24
  • The problem seems to be with `mod_rewrite` and ModSecurity's technical limitations – Riki137 May 03 '19 at 20:21
0

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.

Riki137
  • 2,076
  • 2
  • 23
  • 26
  • I thought this was the case, but after I turn on: SecResponseBodyAccess On it is working as required. – Alvin567 May 30 '21 at 05:51