-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Make multipart boundary check a bit less strict by default #1924
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
Make multipart boundary check a bit less strict by default #1924
Conversation
@airween, your comments and thoughts here would also be very welcome :) |
Oh', I am honoured to be invited, thank you :). After first review, I didn't see the reason, why do you need to create a new rule with less security, but I can imagine that it helps for the administrators in most cases. I think this proposal is closer to the natural use of ModSecurity. I just reviewed the Owasp-CRS rule set, and didn't see any affected rule. Anyway, it would be good to notify the CRS team about this changes. I guess the ModSec users will know it from CHANGES :). I'm afraid I can not add more than above, sorry. :) Thanks again. |
The following cURL command can be used to to illustrate the difference further:
Debug logs from v2/v3 are presented below. Both run using vanilla modsecurity.conf-recommended TLDR; Behaviour is different from v2. v2:
v3:
|
A test case was added at 760e425 that should reproduce the same behaviour as reported above. The interesting thing is that the result of the test case is different from what I expected. For some reason Nginx and Apache connectors have a different behaviour when it comes to validating the MULTIPART_UNMATCHED_BOUNDARY variable. |
I believe this demands further investigation, and being so I'm moving this to the 3.0.4 milestone so we can move ahead with the request and revisit this issue when we have more time. |
I'll check it soon, hope in next few days. |
So, I just could checked with v3, and I don't know what would be the expected result :), but I got these at first run:
As you can see, the 2nd test had failed. As I see the body of request, the boundaries are wrong - here are the patterns:
Now let see the boundaries:
Here you can see, the boundary in header doesn't match with any other boundaries (in body). I think for that reason, the "@eq 1" rule rightfully denied the request. Add plus two "-" signs to header in line 79, or remove two signs from boundary in 85 or 89, and 99 (the valid multipart contains two equal boundary (header and leading), and plus one with "--" signals at the end (trailer)). Hope that's help. |
Hi @airween Your comments and results of are very welcome here. Thank you :) But just to make sure we are on the same page and that I'm not getting the multipart thing incorrectly, do you agree that the boundaries should be specified according to RFC1341: In our case, the boundary is defined like so: Then, each subsequent Content-Disposition will carry the same boundary, but appending "--" to the beginning of the boundary like so:
And the last boundary should be specified with a "--" to the beginning of the boundary and another "--" to the end. Like so:
Regarding the test case, yes it is failing but should be passing I think. I found it interesting that the regression_test ends up having a different behaviour from the Apache/Nginx when it came to validating the MULTIPART_UNMATCHED_BOUNDARY variable. Unless I did something wrong which is a possibility :P |
Well, you're absolutely right - I totally forgot the additionally "-" signs :). Sorry. |
I'll also ask here as it seems to be related one - is it normal that simple request like the following causes 403 triggered by 200004 rule:
? Corresponding request caught by listening on separate port:
|
Changed the default behavior on modsecurity-recommended.conf to not flag the unmatched boundary in that specific use case scenario. By that the behavior is exactly the same as v2. |
Hi @victorhora looks like you've found a bug :). The details - hope this will be clear:
And the bug, what you've found: if you remove the "A" char from the beginning of boundary, the result also will be 2. I reviewed the multipart.cc, and looks like the condition of 'm_flag_unmatched_boundary = 2' assignment isn't correct, because if all boundary matches, then it also evaluated, so the totally well formed request will result with value 2, instead of 0. I've sent a PR to you: https://github.com/victorhora/ModSecurity/pull/1. Please check it, and if you think that's right, approve that. Hope that this will be clean :). |
Hi @defanator
if the rule uses "!@eq 0", then the answer is yes :). That's what I fixed few minutes ago: https://github.com/victorhora/ModSecurity/pull/1 Please check it if you can. |
This pull request is sort of a workaround for multipart/form-data requests that have multiple boundaries such as common
Content-Disposition
POST requests.The issue is that the fix proposed at #1747 and merged at 4d0ca94 could lead to cases where
Content-Disposition
POST requests such as the one below are denied by default after this commit:Ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
I suggesting making rule 200004 less strict by replacing a "deny" with a "pass", but still alerting the WAF operator. The operator can choose the disable or change the rule to not log if need be.
In addition, a new rule (200006) would be created in order to actually block cases where an unmatched boundary is actually found in the request.