8000 Fix FP 953120 brotli compression by franbuehler · Pull Request #2101 · coreruleset/coreruleset · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Fix FP 953120 brotli compression #2101

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed

Conversation

franbuehler
Copy link
Contributor

This PR solves a false positive with Content-Type: br responses by adding a chained rule as discussed in the related issue #2064.

I didn't test this PR and I would be glad if someone else could review and maybe test the chained rule.

@franbuehler franbuehler linked an issue May 24, 2021 that may be closed by this pull request
@franbuehler
Copy link
Contributor Author

Meeting decision June (#2074 (comment)):
@azurit would like to test this PR. Thank you :-)

chain"
SecRule RESPONSE_HEADERS:Content-Encoding "!@streq br" \
"setvar:'tx.outbound_anomaly_score_pl1=+%{tx.error_anomaly_score}',\
setvar:'tx.anomaly_score_pl1=+%{tx.error_anomaly_score}'"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be more efficient to reverse the rules? String equlity check should be much less costly than worst case regexp evaluation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, that's smart. I had not thought of that.
I will switch that. Thank you!

Copy link
Member
@dune73 dune73 Jun 7, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I am not so sure of that. Because the current first rule is really selective. It will fail most of the time. With the reverse order, we run the non-selective rule first and will have to run the 2nd rule almost always on top. So from the perspective of REQUEST_BODY regex inspection not much changed, but an additional rule is running.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hide comment

Yes, but it's a "not" regexp... and the response text could be massive, I suspect? The regexp would be applied to each line in the response body... (I'm guessing here...)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's think about this: the negation isn't part of the regular expression but of the annotation. This means that the regular expression will be applied until it finds a match or the end of the input is reached, only then can the result be checked and negated (unless the engine does some magic on top of PCRE). So for every line of input the expression engine will have to check every branch of the expression against the entire line to check for a match, by eye it looks like there are about 3 top level branches. Even with optimizations, I think the number of operations will be greater than for the string equality check (there's also some overhead for parsing the expression or looking it up from the cache).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What should I do??

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, in reality it probably won't matter too much. The performance gain in either case would be marginal. You choose the explanation that sounds best to you, I suggest ;).

@azurit
Copy link
Member
azurit commented Jun 29, 2021

Sorry for this taking so much time to me! Unfortunately, this solution cannot be used because it will create a way how to bypass rule 953120.

When using a compression done by Apache web server (via mod_deflate for example), data are compressed just before sending them to the client i. e. RESPONSE_HEADERS already contains header Content-Encoding: br but RESPONSE_BODY is still uncompressed (so ModSecurity has access to uncompressed data). When such (very common) case happens, this PR will cause skipping of rule 953120 even if RESPONSE_BODY is uncompressed and contains PHP source code.

How to reproduce bypass (for gzip as i'm not using br but it shouldn't make a difference):

  • use Apache with mod_deflate and mod_filter enabled
  • rename any bigger PHP source code file to something.html (so it's not processed by PHP)

@theseion
Copy link
Contributor

Great catch! I also found your mention of Brotli detection issues: #1968. Basically, as long as we have no reliable way to detect Brotli (e.g. by magic number) we won't be able to do this as we have to assume that response headers can be manipulated, correct? Do you see any other way this could be solved? Or do we maybe need to change the paranoia level of this rule?

@dune73
8000 Copy link
Member
dune73 commented Jul 2, 2021

Let's take this to the chat on Monday. It really is worth a discussion.

@franbuehler
Copy link
Contributor Author

Meeting decision July: #2141 (comment):
@azurit would like to do more tests.

@dune73
Copy link
Member
dune73 commented Aug 2, 2021

Any updates on your tests here @azurit?

@azurit
Copy link
Member
azurit commented Aug 5, 2021

@dune73 Sorry for takeing this so long to me, I'm working on it.

@azurit
Copy link
Member
azurit commented Aug 16, 2021

I did lots of tests and i wasn't able to reproduce my previous behavior, where Content-Encoding is already set but RESPONSE_DATA are available in uncompressed state (but meantime i upgraded everything, including Apache), but i was able to simulate it though (with need of write access to web site files).

Anyway, while testing, i noticed that SecRule RESPONSE_HEADERS:Content-Encoding "!@streq br" don't pass if there's no Content-Encoding header, which makes this rule completely useless:

  • If content is encoded, we skip rule 953120 (we don't see the data anyway).
  • If content isn't encoded, we skip rule 953120 (because there's no Content-Encoding header at all).

This behavior is really weird so, please, anyone, test it too.

@aghontpi
Copy link
aghontpi commented Sep 1, 2021

when will this be merged?

@dune73
Copy link
Member
dune73 commented Sep 2, 2021

Glad you inspected this so carefully, @azurit. Testing this myself now.

@aghontpi : Given we have some serious doubts about the merits of this PR, we can not promise a merge date.

@dune73
Copy link
Member
dune73 commented Sep 2, 2021

OK, I've spent some time on this and I am a bit at a loss. Thank you for taking a deep, deep look at this @azurit.

What I can say is this: When Apache runs mod_brotli, then there is no Content-Encoding header in phase 4, when this rule happens. The CE header is only added by mod_brotli after ModSec phase 4. So this PR effectively kills the rule for this scenario.

If we want to create a workaround for this FP, then I reckon it ought to be a separate rule that sets a variable that we can then check in a chain or something along those lines.

I reckon we also need a decent way to reproduce the FP in question here. We need a src text that triggers 953120 when compressed with brotli. And then a NGINX with brotli, so we can really test it. Apparently the header setting in the phases is different there according to @fl0ppy-d1sk in #2064. Maybe also time to re-open said issue.

@aghontpi
Copy link
aghontpi commented Sep 3, 2021

why isn't there magic bytes for brotli, seriously..

@dune73 , I understand, until then I've just added the filter locally based on content-Encoding, It worked, am using NGINX.

@dune73
Copy link
Member
dune73 commented Sep 3, 2021

I also wonder why that is the case. Probably in order to save space...

You came across these FPs on NGINX, I think. Can you share a payload that leads to an FP when crunched with brotli?

@fl0ppy-d1sk
Copy link

Hey @dune73,

When using NGINX, that image is triggering FP but only when I renamed it to .html and don't know why...

Here is the link.

Hope that helps.

@dune73
Copy link
Member
dune73 commented Sep 3, 2021

Thank you very much @fl0ppy-d1sk. This is very helpful.

It's probably the rainbow hair, though. :)

@dune73
Copy link
Member
dune73 commented Sep 9, 2021

-> We talked about this at the August project meeting but we did not really come up with a solution.

@spartantri suggested we might have to do a rule exclusion package for brotli, that way users could enable the rule exclusion package when they face this situation. That would be better than going something that is on by default and can lead to rule bypasses.

I'm inclined to close the PR and continue the conversation in issue #2064.

Thoughts?

@azurit
Copy link
Member
azurit commented Sep 9, 2021

I still wonder why is SecRule RESPONSE_HEADERS:Content-Encoding "!@streq br" evaluated as False if there is no Content-Encoding header. I mean, it's like if NULL != br i. e. it should be True.

@dune73
Copy link
Member
dune73 commented Sep 13, 2021

Sorry for being late. I wanted to try this out, but now I realize it's far easier.

It does not evaluate to false. It is not evaluated at all. That's because the target list is empty. There is not content-encoding header around, so the rule is being skipped.

What you can do to catch this is &RESPONSE_HEADERS:Content-Encoding.

Please also note that you can play around with the headers by using mod_headers with the flag early that will make sure the header is set before ModSec phase 3.

@azurit
Copy link
Member
azurit commented Oct 4, 2021

We cannot use &RESPONSE_HEADERS:Content-Encoding in current rule as it will disable it for all requests without Content-Encoding header. Do you suggest creating a sibling for rule 953120?

@dune73
Copy link
Member
dune73 commented Oct 4, 2021

Would such a sibling solve our problem? Given this is a broetli-Problem, I think the plugin idea is worth considering. Conceptually a broetlli rule exclusion package.

And then close this PR. Which is kind of sad given all the energy that went into this.

@franbuehler
Copy link
Contributor Author

Meeting decision Oct 4: In fact there is no way to really detect broetli and if broetli is executed on the RP, we won't really know and it's all a mess and despite all the work that went into the review of this PR I think we have to close this. @spartantri proposed to do this as a plugin.

8528 @franbuehler franbuehler closed this Oct 4, 2021
@franbuehler franbuehler deleted the fix-fp-953120-brotli branch February 1, 2024 08:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

brotli compression - false positive
6 participants
0