Skip to content

MULTIPART_STRICT_ERROR False Positive 3.0.4 #2267

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
jeremyjpj0916 opened this issue Feb 12, 2020 · 5 comments
Closed

MULTIPART_STRICT_ERROR False Positive 3.0.4 #2267

jeremyjpj0916 opened this issue Feb 12, 2020 · 5 comments
Assignees

Comments

@jeremyjpj0916
Copy link

jeremyjpj0916 commented Feb 12, 2020

Describe the bug

Trying to do the OAuth2.0 Client Credential grant type with Content-Type: multipart/form-data with a boundary. Sample below:

(Creds redacted)

POST https://gateway.company.com/auth/oauth2/token HTTP/1.1

Content-Type: multipart/form-data; boundary="----=_Part_8_900587478.1581545086929"
Accept-Encoding: gzip,deflate
MIME-Version: 1.0
Content-Length: 644
Host: gateway.company.com
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)


------=_Part_8_900587478.1581545086929
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: form-data; name="client_id"

XXXXXXXXXXXXXXXXXXXXXX
------=_Part_8_900587478.1581545086929
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: form-data; name="client_secret"

XXXXXXXXXXXXXXXXXXXXXX
------=_Part_8_900587478.1581545086929
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: form-data; name="grant_type"

client_credentials
------=_Part_8_900587478.1581545086929--

Note this was produced by the SOAPUI REST client, so I would think it to be entirely valid
multipart/form-data with a boundary.

Logs and dumps

2020/02/12 22:04:49 [error] 73#0: *475706 [client 10.96.3.174] ModSecurity: Access denied with code 400 (phase 2). Matched "Operator `Eq' with parameter `0' against variable `MULTIPART_STRICT_ERROR' (Value: `1' ) [file "/ModSecurity/modsecurity.conf"] [line "17"] [id "200003"] [rev ""] [msg "Multipart request body failed strict validation: \\x0aPE 0, \\x0aBQ 1, \\x0aBW 0, \\x0aDB 1, \\x0aDA 0, \\x0aHF 0, \\x0aLF 0, \\x0aSM 0, \\x0aIQ 0, \\x0aIP 0, \\x0aIH 0, \\x0aFL "] [data ""] [severity "0"] [ver ""] [maturity "0"] [accuracy "0"] [hostname "10.131.91.23"] [uri "/auth/oauth2/token"] [unique_id "158154508955.517917"] [ref "v320,1"], client: 10.96.3.174, server: kong, request: "POST /auth/oauth2/token HTTP/1.1", host: "gateway.company.com"

Any harm in commenting out these portions of the rules in the meantime???

# BQ %{MULTIPART_BOUNDARY_QUOTED}, \
# DB %{MULTIPART_DATA_BEFORE}, \
# FL %{MULTIPART_FILE_LIMIT_EXCEEDED}

SecRule MULTIPART_STRICT_ERROR "!@eq 0" \
"id:'200003',phase:2,t:none,log,deny,status:400, \
msg:'Multipart request body failed strict validation: \
PE %{REQBODY_PROCESSOR_ERROR}, \
BW %{MULTIPART_BOUNDARY_WHITESPACE}, \
DA %{MULTIPART_DATA_AFTER}, \
HF %{MULTIPART_HEADER_FOLDING}, \
LF %{MULTIPART_LF_LINE}, \
SM %{MULTIPART_MISSING_SEMICOLON}, \
IQ %{MULTIPART_INVALID_QUOTING}, \
IP %{MULTIPART_INVALID_PART}, \
IH %{MULTIPART_INVALID_HEADER_FOLDING}'"

Expected behavior

Plz don't block me 😄

@jeremyjpj0916
Copy link
Author

jeremyjpj0916 commented Feb 12, 2020

Also the last field \x0aFL "] not printing a 0 or 1 is interesting/a bug i imagine, turns out it was set to 1(I think?) internally though cause when we pulled it out for an extra test to pass WAF checking, thats was what finally let strict validation rule pass w/out blocking the tx.

@martinhsv martinhsv self-assigned this Feb 13, 2020
@martinhsv
Copy link
Contributor

martinhsv commented Feb 13, 2020

Hi @jeremyjpj0916 ,

Those three lines that you highlight from the definition of rule 200003 in modsecurity.conf really only control log output, so removing them will not stop the false positives (i.e. removal would just omit the 'BQ 1' (etc.) from the log output).

To stop the false positives, a couple of options that you could consider:

  • modify your rule that checks MULTIPART_STRICT_ERROR to not result in a blocking action (i.e. use detection only)
  • maintain blocking, but instead of using MULTIPART_STRICT_ERROR, check each of the individual variables (e.g. MULTIPART_INVALID_PART) except for the one(s) that are causing well-understood false-positives

Some of the conditions checked within MULTIPART_STRICT_ERROR are RFC-compliant, but are (or were) unusual, and so, possibly suspicious. Reports from the community are useful in guiding whether we should revisit some aspects of the implementation, so thank you for reporting it.

Thanks also for mentioning the 'FL' log output anomaly. Yes, it's probably a bug; I'll have a look into that.

@jeremyjpj0916
Copy link
Author

jeremyjpj0916 commented Feb 13, 2020

@martinhsv appreciate the prompt feedback. Yes we are indeed breaking out the rules individually and assigning them unique id's now(yeah we goofed just messing with the print statement originally hah) and commenting out the necessary ones to get this payload working.

@rsbrisci
Copy link

rsbrisci commented Feb 13, 2020

@martinhsv Hi! I work with @jeremyjpj0916
Currently giving this a shot!

### Disable MultiPart Strict Rule - Broken out into Individiual rules
# SecRule MULTIPART_STRICT_ERROR "!@eq 0" \
# "id:'200003',phase:2,t:none,log,deny,status:400, \
# msg:'Multipart request body failed strict validation: \
# PE %{REQBODY_PROCESSOR_ERROR}, \
# DB %{MULTIPART_DATA_BEFORE}. \
# BW %{MULTIPART_BOUNDARY_WHITESPACE}, \
# BQ %{MULTIPART_BOUNDARY_QUOTED}, \
# DA %{MULTIPART_DATA_AFTER}, \
# HF %{MULTIPART_HEADER_FOLDING}, \
# LF %{MULTIPART_LF_LINE}, \
# SM %{MULTIPART_MISSING_SEMICOLON}, \
# IQ %{MULTIPART_INVALID_QUOTING}, \
# IP %{MULTIPART_INVALID_PART}, \
# IH %{MULTIPART_INVALID_HEADER_FOLDING}, \
# FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'"

### Start Individual Multipart Media Type Rules
SecRule REQBODY_PROCESSOR_ERROR "!@eq 0" \
"id:'200003',phase:2,t:none,log,deny,status:400, \
msg:'Multipart request body failed custom validation: DB %{REQBODY_PROCESSOR_ERROR}.'"

# Disabled b/c interference with compliant OAuth2 CC Token Generation
# SecRule MULTIPART_DATA_BEFORE "!@eq 0" \
# "id:'200006',phase:2,t:none,log,deny,status:400, \
# msg:'Multipart request body failed custom  validation: DB %{MULTIPART_DATA_BEFORE}.'"

SecRule MULTIPART_BOUNDARY_WHITESPACE "!@eq 0" \
"id:'200007',phase:2,t:none,log,deny,status:400, \
msg:'Multipart request body failed custom  validation: DB %{MULTIPART_BOUNDARY_WHITESPACE}.'"

# Disabled b/c interference with compliant OAuth2 CC Token Generation
# SecRule MULTIPART_BOUNDARY_QUOTED "!@eq 0" \
# "id:'200008',phase:2,t:none,log,deny,status:400, \
# msg:'Multipart request body failed custom  validation: DB %{MULTIPART_BOUNDARY_QUOTED}.'"

SecRule MULTIPART_DATA_AFTER "!@eq 0" \
"id:'200009',phase:2,t:none,log,deny,status:400, \
msg:'Multipart request body failed custom  validation: DB %{MULTIPART_DATA_AFTER}.'"

SecRule MULTIPART_HEADER_FOLDING "!@eq 0" \
"id:'200010',phase:2,t:none,log,deny,status:400, \
msg:'Multipart request body failed custom  validation: DB %{MULTIPART_HEADER_FOLDING}.'"

SecRule MULTIPART_LF_LINE "!@eq 0" \
"id:'200011',phase:2,t:none,log,deny,status:400, \
msg:'Multipart request body failed custom  validation: DB %{MULTIPART_LF_LINE}.'"

SecRule MULTIPART_MISSING_SEMICOLON "!@eq 0" \
"id:'200012',phase:2,t:none,log,deny,status:400, \
msg:'Multipart request body failed custom  validation: DB %{MULTIPART_MISSING_SEMICOLON}.'"

SecRule MULTIPART_INVALID_QUOTING "!@eq 0" \
"id:'200013',phase:2,t:none,log,deny,status:400, \
msg:'Multipart request body failed custom  validation: DB %{MULTIPART_INVALID_QUOTING}.'"

SecRule MULTIPART_INVALID_PART "!@eq 0" \
"id:'200014',phase:2,t:none,log,deny,status:400, \
msg:'Multipart request body failed custom  validation: DB %{MULTIPART_INVALID_PART}.'"

SecRule MULTIPART_INVALID_HEADER_FOLDING "!@eq 0" \
"id:'200015',phase:2,t:none,log,deny,status:400, \
msg:'Multipart request body failed custom  validation: DB %{MULTIPART_INVALID_HEADER_FOLDING}.'"

SecRule MULTIPART_FILE_LIMIT_EXCEEDED "!@eq 0" \
"id:'200016',phase:2,t:none,log,deny,status:400, \
msg:'Multipart request body failed custom  validation: DB %{MULTIPART_FILE_LIMIT_EXCEEDED}.'"

### End Individual Multipart Media Type Rules

edit: DB in all my log statements ofcourse leading to confusing logs. Have rectified :P

@rsbrisci
Copy link

That did the trick!

Now the OWASP CRS has found a reason to block this request, but we're past the ModSecurity rules. Thank you for your help!

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

No branches or pull requests

4 participants