I have been thinking a lot recently about XSS Attacks and how ModSecurity can
potentially identify these attacks and respond -
http://www.modsecurity.org/documentation/XSS_Street_Fight-Ryan_Barnett-BlackhatDC-2011.pdf
I would like to get some community feedback on a possible new approach for XSS.
The big current issue I see with the ModSecurity CRS approach is that the rules
are looking for potentially malicious input and flagging them as XSS and
executing blocking. This approach is flawed for 2 reasons -
1. Many of the XSS signatures are too broad and are looking for any html data
on inbound. This may work OK if the application or specific parameter is never
supposed to contain html code, however many users have apps that allow for some
html code on the inbound. There are many ModSecurity users who get upset
because the rules end up blocking normal transaction in applications like
WordPress. The XSS signatures should probably be broken up into separate files
- 1) Malicious code – which would only contain signatures for confirmed,
malicious code. These rules can be acted upon for blocking actions in any
circumstance. 2) Html code – which would trigger on any html-like code. This
could be activated for sites that don't allow any html code.
2. Blocking inbound data for XSS is prone to False Positives. XSS manifests
itself when client-supplied data is echoed back out to clients in a non-escaped
format. The applications may actually be properly output escaping
user-supplied data and they don't need for ModSecurity to do any blocking. It
seems that the best place to choose a blocking action for XSS is actually in
the response back to the client.
Here is an example approach for #2 above.
We are already flagging inbound data as potential XSS attacks and saving the
data in TX variables. If we were to not block for XSS on the inbound, but
instead inspect the RESPONSE_BODY variables for matches of TX XSS data, we
could then choose to block. Here is an example rule which does just that -
SecRule TX:/XSS/ "@within %{response_body}"
"phase:4,t:none,log,block,msg:'Malicious Client Data Found in Response
Page.',logdata:'%{matched_var}'"
As a test, I sent the following request (from the ModSec audit log) -
###############################
--25ab4619-B--
POST /cgi-bin/fup.cgi HTTP/1.1
Host: localhost
Connection: keep-alive
Referer: http://localhost/upload.html
Content-Length: 429
Cache-Control: max-age=0
Origin: http://localhost
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en-US)
AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.204 Safari/534.16
Content-Type: multipart/form-data;
boundary=----WebKitFormBoundary5l4ChTnz96IS0ru8
Accept:
application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
--25ab4619-I--
note=%3cscript%3ealert%28%27xss%27%29%3c%2fscript%3e
--25ab4619-F--
HTTP/1.1 200 OK
Content-Length: 308
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html
--25ab4619-E--
<html>
<head>
<title>File Upload Results</title>
</head>
<body>
<h1>File Upload Results</h1>
<p>You've uploaded a file. Your notes on the file were:<br>
<blockquote><script>alert('xss')</script></blockquote><br>
<p>The file's contents are:
<pre>
</pre>
</body>
</html>
###############################
The new rule generated a number of events -
[Thu Apr 14 11:00:59 2011] [error] [client ::1] ModSecurity: Warning. String
match within "<html>\\n<head>\\n<title>File Upload
Results</title>\\n</head>\\n<body>\\n<h1>File Upload
Results</h1>\\n\\n<p>You've uploaded a file. Your notes on the file
were:<br>\\n<blockquote><script>alert('xss')</script></blockquote><br>\\n<script></script>\\n<script></script>\\n<p>The
file's contents are:\\n<pre>\\n\\n</pre>\\n</body>\\n</html>\\n" at
TX:958052-WEB_ATTACK/XSS-ARGS:note. [file
"/usr/local/apache/conf/crs/base_rules/modsecurity_crs_15_customrules.conf"]
[line "17"] [msg "Malicious Client Data Found n Response Page."] [data
"alert("] [hostname "localhost"] [uri "/cgi-bin/fup.cgi"] [unique_id
"TacMK8CoqAEAAKdOIfUAAAAB"]
[Thu Apr 14 11:00:59 2011] [error] [client ::1] ModSecurity: Warning. String
match within "<html>\\n<head>\\n<title>File Upload
Results</title>\\n</head>\\n<body>\\n<h1>File Upload
Results</h1>\\n\\n<p>You've uploaded a file. Your notes on the file
were:<br>\\n<blockquote><script>alert('xss')</script></blockquote><br>\\n<script></script>\\n<script></script>\\n<p>The
file's contents are:\\n<pre>\\n\\n</pre>\\n</body>\\n</html>\\n" at
TX:958051-WEB_ATTACK/XSS-ARGS:note. [file
"/usr/local/apache/conf/crs/base_rules/modsecurity_crs_15_customrules.conf"]
[line "17"] [msg "Malicious Client Data Found n Response Page."] [data
"<script"] [hostname "localhost"] [uri "/cgi-bin/fup.cgi"] [unique_id
"TacMK8CoqAEAAKdOIfUAAAAB"]
[Thu Apr 14 11:00:59 2011] [error] [client ::1] ModSecurity: Warning. String
match within "<html>\\n<head>\\n<title>File Upload
Results</title>\\n</head>\\n<body>\\n<h1>File Upload
Results</h1>\\n\\n<p>You've uploaded a file. Your notes on the file
were:<br>\\n<blockquote><script>alert('xss')</script></blockquote><br>\\n<script></script>\\n<script></script>\\n<p>The
file's contents are:\\n<pre>\\n\\n</pre>\\n</body>\\n</html>\\n" at
TX:973300-WEB_ATTACK/XSS-ARGS:note. [file
"/usr/local/apache/conf/crs/base_rules/modsecurity_crs_15_customrules.conf"]
[line "17"] [msg "Malicious Client Data Found n Response Page."] [data
"<script>"] [hostname "localhost"] [uri "/cgi-bin/fup.cgi"] [unique_id
"TacMK8CoqAEAAKdOIfUAAAAB"]
[Thu Apr 14 11:00:59 2011] [error] [client ::1] ModSecurity: Warning. String
match within "<html>\\n<head>\\n<title>File Upload
Results</title>\\n</head>\\n<body>\\n<h1>File Upload
Results</h1>\\n\\n<p>You've uploaded a file. Your notes on the file
were:<br>\\n<blockquote><script>alert('xss')</script></blockquote><br>\\n<script></script>\\n<script></script>\\n<p>The
file's contents are:\\n<pre>\\n\\n</pre>\\n</body>\\n</html>\\n" at
TX:973307-WEB_ATTACK/XSS-ARGS:note. [file
"/usr/local/apache/conf/crs/base_rules/modsecurity_crs_15_customrules.conf"]
[line "17"] [msg "Malicious Client Data Found n Response Page."] [data
"alert("] [hostname "localhost"] [uri "/cgi-bin/fup.cgi"] [unique_id
"TacMK8CoqAEAAKdOIfUAAAAB"]
[Thu Apr 14 11:00:59 2011] [error] [client ::1] ModSecurity: Warning. String
match within "<html>\\n<head>\\n<title>File Upload
Results</title>\\n</head>\\n<body>\\n<h1>File Upload
Results</h1>\\n\\n<p>You've uploaded a file. Your notes on the file
were:<br>\\n<blockquote><script>alert('xss')</script></blockquote><br>\\n<script></script>\\n<script></script>\\n<p>The
file's contents are:\\n<pre>\\n\\n</pre>\\n</body>\\n</html>\\n" at
TX:973310-WEB_ATTACK/XSS-ARGS:note. [file
"/usr/local/apache/conf/crs/base_rules/modsecurity_crs_15_customrules.conf"]
[line "17"] [msg "Malicious Client Data Found n Response Page."] [data "'xss'"]
[hostname "localhost"] [uri "/cgi-bin/fup.cgi"] [unique_id
"TacMK8CoqAEAAKdOIfUAAAAB"]
[Thu Apr 14 11:00:59 2011] [error] [client ::1] ModSecurity: Warning. String
match within "<html>\\n<head>\\n<title>File Upload
Results</title>\\n</head>\\n<body>\\n<h1>File Upload
Results</h1>\\n\\n<p>You've uploaded a file. Your notes on the file
were:<br>\\n<blockquote><script>alert('xss')</script></blockquote><br>\\n<script></script>\\n<script></script>\\n<p>The
file's contents are:\\n<pre>\\n\\n</pre>\\n</body>\\n</html>\\n" at
TX:973331-WEB_ATTACK/XSS-ARGS:note. [file
"/usr/local/apache/conf/crs/base_rules/modsecurity_crs_15_customrules.conf"]
[line "17"] [msg "Malicious Client Data Found n Response Page."] [data
"<script>"] [hostname "localhost"] [uri "/cgi-bin/fup.cgi"] [unique_id
"TacMK8CoqAEAAKdOIfUAAAAB"]
This approach seems to me to be more accurate for detecting/reacting to XSS as
you are doing the inspection/blocking in the outbound which means that you have
less false positives.
Now, taking this approach one step further! With the upcoming ModSecurity v2.6
– you could actually extend the rule logic to use @rsub against the
STREAM_OUTPUT_BODY and actually remove malicious code from response bodies and
still send the page :)
SecRule TX:/XSS/ "@within %{response_body}"
"chain,phase:4,t:none,log,pass,msg:'Malicious Client Data Removed From Response
Page.',logdata:'%{matched_var}'"
SecRule STREAM_OUTPUT_BODY "@rsub
s/%{matched_var}/MALICIOUS_CODE_REMOVED/d"
Running new ruleset – this is how the reflected XSS attack response page would
look to a client -
$ curl "http://localhost/cgi-bin/fup.cgi?note=<script>alert('xss')</script>"
<html>
<head>
<title>File Upload Results</title>
</head>
<body>
<h1>File Upload Results</h1>
<p>You've uploaded a file. Your notes on the file were:<br>
<blockquote>MALICIOUS_CODE_REMOVEDalert('xss')</script></blockquote><br>
<p>The file's contents are:
<pre>
</pre>
</body>
</html>
Comments welcome!
-Ryan
________________________________
This transmission may contain information that is privileged, confidential,
and/or exempt from disclosure under applicable law. If you are not the intended
recipient, you are hereby notified that any disclosure, copying, distribution,
or use of the information contained herein (including any reliance thereon) is
STRICTLY PROHIBITED. If you received this transmission in error, please
immediately contact the sender and destroy the material in its entirety,
whether in electronic or hard copy format.
_______________________________________________
Owasp-modsecurity-core-rule-set mailing list
[email protected]
https://lists.owasp.org/mailman/listinfo/owasp-modsecurity-core-rule-set