Top Banner
Web Integration Patterns In the Era of HTML5 @johnwilander at OWASP BeNeLux 2012, Leuven, Belgium GeekMeet Stockholm, Sweden, 2013
83

Web Integration Patterns in the Era of HTML5

May 10, 2015

Download

Documents

johnwilander

Presentation given at OWASP BeNeLux November 2012 and GeekMeet Stockholm January 2013. Covers secure and robust integration patterns for the web using cross origin resource sharing (CORS), sandboxed iframes, and the postMessage API.
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Web Integration Patterns in the Era of HTML5

Web Integration Patterns In the Era of HTML5

@johnwilander atOWASP BeNeLux 2012, Leuven, BelgiumGeekMeet Stockholm, Sweden, 2013

Page 2: Web Integration Patterns in the Era of HTML5

@johnwilander

Part IThe Historyof Web Integration

Page 3: Web Integration Patterns in the Era of HTML5

@johnwilander

Remember when we had pages?

Page 4: Web Integration Patterns in the Era of HTML5

@johnwilander

… maybe a persistent menu system?

Menu

Page 5: Web Integration Patterns in the Era of HTML5

@johnwilander

Menu

… and 3rd party popus?

Page 6: Web Integration Patterns in the Era of HTML5

@johnwilander

You still see such sites.

Page 7: Web Integration Patterns in the Era of HTML5

@johnwilander

But product owners don’t want them

anymore.

Page 8: Web Integration Patterns in the Era of HTML5

@johnwilander

Menu

So we started loading things when we needed them, using Ajax and DOM manipulation with JavaScript.

Page 9: Web Integration Patterns in the Era of HTML5

@johnwilander

Menu

Page 10: Web Integration Patterns in the Era of HTML5

@johnwilander

Menu

The problem was that Ajax was only allowed to the same origin as the page. Ergo, no third party integration.

Page 11: Web Integration Patterns in the Era of HTML5

@johnwilander

But the same-origin policy didn’t apply to all

web elements.

Page 12: Web Integration Patterns in the Era of HTML5

@johnwilander

<form action="http://3rdparty.net"></form>

<img src="http://3rdparty.net">

<script src="http://3rdparty.net"></script>

Page 13: Web Integration Patterns in the Era of HTML5

@johnwilander

<form action="http://3rdparty.net"></form>

<img src="http://3rdparty.net">

<script src="http://3rdparty.net"></script>

The form tag actually had cross-domain intentions and is used for integration with e.g. payment providers such as PayPal. You post a purchase form from maindomain.com and enter the checkout process at paypal.com.

Page 14: Web Integration Patterns in the Era of HTML5

@johnwilander

<form action="http://3rdparty.net"></form>

<img src="http://3rdparty.net">

<script src="http://3rdparty.net"></script>The img tag has been used heavily for cross-origin web tracking such as Google Analytics and Omniture.

Page 15: Web Integration Patterns in the Era of HTML5

@johnwilander

Image srchttp://www.google-analytics.com/__utm.gif?utmwv=5.3.8&utms=1&utmn=1854976096&utmhn=appsandsecurity.blogspot.se&utmcs=UTF-8&utmsr=1920x1200&utmvp=1268x500&utmsc=24-bit&utmul=sv&utmje=1&utmfl=11.5%20r31&utmdt=Apps%20and%20Security&utmhid=2120874108&utmr=-&utmp=%2F&utmac=UA-6984098-5&utmcc=__utma%3D60396157.1187947367.1352854596.1353863861.1353882126.6%3B%2B__utmz%3D60396157.1352933082.2.2.utmcsr%3Dgoogle%7Cutmccn%3D(organic)%7Cutmcmd%3Dorganic%7Cutmctr%3D(not%2520provided)%3B&utmu=q~

Query string parametersutmwv:5.3.8utms:1utmn:1854976096utmhn:appsandsecurity.blogspot.seutmcs:UTF-8utmsr:1920x1200utmvp:1268x500utmsc:24-bitutmul:svutmje:1utmfl:11.5 r31utmdt:Apps and Securityutmhid:2120874108utmr:-utmp:/utmac:UA-6984098-5utmcc:__utma=60396157.1187947367.1352854596.1353863861.1353882126.6;+__utmz=60396157.1352933082.2.2.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided);utmu:q~

Page 16: Web Integration Patterns in the Era of HTML5

@johnwilander

<form action="http://3rdparty.net"></form>

<img src="http://3rdparty.net">

<script src="http://3rdparty.net"></script>

The script tag became the workhorse for Ajax-like cross-origin sharing by means of the popular jsonp hack.

Page 17: Web Integration Patterns in the Era of HTML5

@johnwilander

Jsonp =Json with Padding

(should be ”Json, Please?”)

Page 18: Web Integration Patterns in the Era of HTML5

@johnwilander

maindomain.com

3rdparty.net

<html>

<script> function receive(data) { var json = JSON.parse(data); ... };</script>

</html>

Jsonp

Page 19: Web Integration Patterns in the Era of HTML5

@johnwilander

maindomain.com

3rdparty.net

<html>

<script> function receive(data) { var json = JSON.parse(data); ... };</script>

</html>

Inserts a new script element toretrieve data cross-domain

Jsonp

Page 20: Web Integration Patterns in the Era of HTML5

@johnwilander

maindomain.com

3rdparty.net

<html>

<script> function receive(data) { var json = JSON.parse(data); ... };</script>

<script src=”3rdparty.net/getData?cb=receive”></script>

</html>

Inserts a new script element toretrieve data cross-domain.

Jsonp

Page 21: Web Integration Patterns in the Era of HTML5

@johnwilander

maindomain.com

3rdparty.net

<html>

<script> function receive(data) { var json = JSON.parse(data); ... };</script>

<script src=”3rdparty.net/getData?cb=receive”></script>

</html>

Jsonp

Page 22: Web Integration Patterns in the Era of HTML5

@johnwilander

maindomain.com

3rdparty.net

<html>

<script> function receive(data) { var json = JSON.parse(data); ... };</script>

<script src=”3rdparty.net/getData?cb=receive”></script>

</html>

The third party domain ”pads” theresponse data with a call to the given callback function.

Jsonp

Page 23: Web Integration Patterns in the Era of HTML5

@johnwilander

maindomain.com

3rdparty.net

<html>

<script> function receive(data) { var json = JSON.parse(data); ... };</script>

<script src=”3rdparty.net/getData?cb=receive”></script>

</html>

receive({ ”prop1”: ”data”, ”prop2”: ”data”, ”prop3”: ”data”, ”prop4”: ”data”});

Jsonp

Page 24: Web Integration Patterns in the Era of HTML5

@johnwilander

maindomain.com

3rdparty.net

<html>

<script> function receive(data) { var json = JSON.parse(data); ... };</script>

</html>

{ ”prop1”: ”data”, ”prop2”: ”data”, ”prop3”: ”data”, ”prop4”: ”data”}

receive({ ”prop1”: ”data”, ”prop2”: ”data”, ”prop3”: ”data”, ”prop4”: ”data”});

Jsonp

Page 25: Web Integration Patterns in the Era of HTML5

@johnwilander

maindomain.com

3rdparty.net

<html>

<script> function receive(data) { var json = JSON.parse(data); ... };</script>

</html>

{ ”prop1”: ”data”, ”prop2”: ”data”, ”prop3”: ”data”, ”prop4”: ”data”}

receive({ ”prop1”: ”data”, ”prop2”: ”data”, ”prop3”: ”data”, ”prop4”: ”data”});

Jsonp

Data is fetched asynchronously, cross-domain.

Page 30: Web Integration Patterns in the Era of HTML5

@johnwilander

jQuery's ”crossDomain” Ajax is Jsonp

http://api.jquery.com/jQuery.ajax/

Page 31: Web Integration Patterns in the Era of HTML5

@johnwilander

Jsonp Is Inherently Dangerous

Benign server response: givenCallback({”prop1”: ”val1”});

Compromised server response: givenCallback({”prop1”: ”val1”}); evilCode(); moreEvilCode();

Page 32: Web Integration Patterns in the Era of HTML5

@johnwilander

Jsonp Is Inherently Dangerous

Benign server response: givenCallback({”prop1”: ”val1”});

Compromised server response: givenCallback({”prop1”: ”val1”}); evilCode(); moreEvilCode();

Note that a client doing jsonp calls has nochance to see/filter the reponse before it’s executed.The client has to blindly trust whatever code is returned.

Page 33: Web Integration Patterns in the Era of HTML5

@johnwilander

Jsonp and CSRF

Also, all relevant cookies for the Jsonp service are sent with the request opening up for non-blind CSRF. Non-blind as in the attacker getting the response in full.

Page 34: Web Integration Patterns in the Era of HTML5

@johnwilander

Demo jsonp

Page 35: Web Integration Patterns in the Era of HTML5

@johnwilander

Then there is the document.domain

trick.

Page 36: Web Integration Patterns in the Era of HTML5

@johnwilander

main.1-liner.org

other.1-liner.org

Page 37: Web Integration Patterns in the Era of HTML5

@johnwilander

main.1-liner.org

other.1-liner.org

Page 38: Web Integration Patterns in the Era of HTML5

@johnwilander

main.1-liner.org

other.1-liner.org

Page 39: Web Integration Patterns in the Era of HTML5

@johnwilander

main.1-liner.org

other.1-liner.org

Same-origin policyprohibits evendifferent subdomainsfrom interacting

Page 40: Web Integration Patterns in the Era of HTML5

@johnwilander

main.1-liner.org

document.domain = ”1-liner.org”;

other.1-liner.org

document.domain = ”1-liner.org”;

Page 41: Web Integration Patterns in the Era of HTML5

@johnwilander

main.1-liner.org

document.domain = ”1-liner.org”;

other.1-liner.org

document.domain = ”1-liner.org”;

Page 42: Web Integration Patterns in the Era of HTML5

@johnwilander

main.1-liner.org

document.domain = ”1-liner.org”;

main.1-liner.org

But …

Page 43: Web Integration Patterns in the Era of HTML5

@johnwilander

Demo document.domain

Page 44: Web Integration Patterns in the Era of HTML5

@johnwilander

In summary, web integration used to be

all-or-nothing.

Page 45: Web Integration Patterns in the Era of HTML5

@johnwilander

Part 2New Integration Technologies

Page 46: Web Integration Patterns in the Era of HTML5

@johnwilander

CORS var req = new XMLHttpRequest(); req.open(method, crossDomainUrl); req.send();

Sandboxed iframes <iframe src="http://3rdparty.net" sandbox="allow-scripts"></iframe>

postMessage API otherFrameOrWindow.postMessage( ’{"action": "purchase", "item": 34443}’, "http://3rdparty.net");

Page 47: Web Integration Patterns in the Era of HTML5

@johnwilander

Cross-Origin Resource Sharing, CORS

10+Partial supportin IE8 and IE9

15+

5.1+

22+

12+

3.2+

2.1+

http://caniuse.com/#search=cors

Page 48: Web Integration Patterns in the Era of HTML5

@johnwilander

CORS is basically cross-origin Ajax

Page 49: Web Integration Patterns in the Era of HTML5

@johnwilander

CORS

• The server has to authorize requests in response headers: Access-Control-Allow-Origin allowed.domain.com

• HTTP GET and POST are like normal Ajax

• Other HTTP methods or GET and POST with custom headers require a preflight

• The client has to explicitly send cookies: xhr.withCredentials = true;

Page 50: Web Integration Patterns in the Era of HTML5

@johnwilander

CORS-Unaware Server

Let's see what 2012 looks like if we are still running a …

Page 51: Web Integration Patterns in the Era of HTML5

@johnwilander

CORS-Unaware ServerClient Server

Ajax GET

Looks likea normal GET.Has a reliable Origin header.

If no authori-zation logic is present it just responds.

If no allowing CORS header client gets no response.

No cookies

Page 52: Web Integration Patterns in the Era of HTML5

@johnwilander

CORS-Unaware ServerClient Server

Ajax POST

Looks likea normal POST.Has a reliable Origin header.

If no authori-zation logic is present it just responds.

If no allowing CORS header client gets no response.

No cookies

Page 53: Web Integration Patterns in the Era of HTML5

@johnwilander

CORS-Unaware ServerClient Server

Looks like a normal request.Has a reliable Origin header.

If no authori-zation logic is present it just responds.

If no allowing CORS header client gets no response.

CookiesAjax + withCredentials = true;

Page 54: Web Integration Patterns in the Era of HTML5

@johnwilander

CORS-Unaware ServerClient Server

OPTIONS request with Access-Control-Request-Method: GET/POST

If no authori-zation logic is present it just responds.

If no allowing CORS header client never sends request.

Preflight requestAjax + setRequestHeader('X-Requested-With','XMLHttpRequest');

Page 55: Web Integration Patterns in the Era of HTML5

@johnwilander

CORS-Aware ServerClient Server

Looks like a normal request.Has a reliable Origin header.

Authorizes the calling origin and includesAccess-Control-Allow-Origin

If allowing CORS header client gets the response.

CookiesAjax + withCredentials = true;

Page 56: Web Integration Patterns in the Era of HTML5

@johnwilander

This means …

• Attackers can now do CSRF without img tags or form posting.

• Servers that don’t check origin headers have no clue it’s a cross-origin Ajax call.

• Custom headers including the Ajax header are effectively dead in the CORS case since developers want to avoid preflights.

Page 57: Web Integration Patterns in the Era of HTML5

@johnwilander

DEMO CORS

Page 58: Web Integration Patterns in the Era of HTML5

@johnwilander

Sandboxed iframes

10+Rumored to

not be there yet

17+

5.1+

22+

Nosupport

4.2+

2.2+

http://caniuse.com/#feat=iframe-sandbox

Page 59: Web Integration Patterns in the Era of HTML5

@johnwilander

main.1-liner.org

<iframe src=”main.1-liner.org” sandbox>

<script></script><form></form>

</iframe>

Sandboxed iframe

Page 60: Web Integration Patterns in the Era of HTML5

@johnwilander

main.1-liner.org

<iframe src=”main.1-liner.org” sandbox=”allow-same- origin”>

<script></script><form></form></iframe>

Sandboxed iframe

Page 61: Web Integration Patterns in the Era of HTML5

@johnwilander

main.1-liner.org

<iframe src=”main.1-liner.org” sandbox=”allow-same- origin allow-scripts”>

<script></script><form></form></iframe>

Sandboxed iframe

Page 62: Web Integration Patterns in the Era of HTML5

@johnwilander

main.1-liner.org

<iframe src=”main.1-liner.org” sandbox=”allow-same- origin allow-scripts allow-forms”><script></script><form></form></iframe>

Sandboxed iframe

Page 63: Web Integration Patterns in the Era of HTML5

@johnwilander

DEMO Sandboxed iframe

Page 64: Web Integration Patterns in the Era of HTML5

@johnwilander

Partialsupport inIE8 – IE10

15+

5.1+

22+

12+

3.2+

2.1+

http://caniuse.com/#search=postMessage

postMessage

Page 65: Web Integration Patterns in the Era of HTML5

@johnwilander

postMessage

• Allows string-based communication between frames and windows

• You need a handle to the target to be able to send a message

• The recipient whitelists origins from which it accepts messages

Page 66: Web Integration Patterns in the Era of HTML5

@johnwilander

postMessage// Sending messages requires a handle to the receiving endvar popup = window.open("http://other.1-liner.org", "_blank");popup.postMessage("Luke, I am your father.", "http://other.1-liner.org");

// Receiving messages requires an event listenerreceiveMessage = function(event) { if (event.origin !== "http://other.1-liner.org") { return; } console.log(event.data);}window.addEventListener("message", receiveMessage, false);

Page 67: Web Integration Patterns in the Era of HTML5

@johnwilander

postMessage// Sending messages requires a handle to the receiving endvar popup = window.open("http://other.1-liner.org", "_blank");popup.postMessage("Luke, I am your father.", "http://other.1-liner.org");

// Receiving messages requires an event listenerreceiveMessage = function(event) { if (event.origin !== "http://other.1-liner.org") { return; } console.log(event.data);}window.addEventListener("message", receiveMessage, false);

Handle to receiving

window or frame

Target origin makes sure the window

or frame hasn’t been redirected

Page 68: Web Integration Patterns in the Era of HTML5

@johnwilander

postMessage// Sending messages requires a handle to the receiving endvar popup = window.open("http://other.1-liner.org", "_blank");popup.postMessage("Luke, I am your father.", "http://other.1-liner.org");

// Receiving messages requires an event listenerreceiveMessage = function(event) { if (event.origin !== "http://other.1-liner.org") { return; } console.log(event.data);}window.addEventListener("message", receiveMessage, false);

Receiving event listener has to check the message

comes from a trusted origin

Page 69: Web Integration Patterns in the Era of HTML5

@johnwilander

DEMO postMessage

Page 70: Web Integration Patterns in the Era of HTML5

@johnwilander

Part 3How To Use the Technologies Securely

Page 71: Web Integration Patterns in the Era of HTML5

@johnwilander

First stop using …

• Jsonp

• document.location trick

• img tag trick

Page 72: Web Integration Patterns in the Era of HTML5

@johnwilander

Implement CORS Server-Side Now

Client ServerAlways check origin header.

Authorize the calling origin based on a whitelist.

If allowing CORS header client gets the response.

CookiesAjax + withCredentials = true;

Page 73: Web Integration Patterns in the Era of HTML5

@johnwilander

HTML

HTML

HTML

CSS

CSS

JavaScript

JavaScript

CSS

JavaScript

Bad Web Architecture

Page 74: Web Integration Patterns in the Era of HTML5

@johnwilander

HTML

CSS on file

JavaScript on file

Import

CSS

JavaScript

Good Web Architecture

Page 75: Web Integration Patterns in the Era of HTML5

@johnwilander

A good separation of content, code, and style

allows for CSP.

Page 76: Web Integration Patterns in the Era of HTML5

@johnwilander

But our legacy applications are a mess.

Page 77: Web Integration Patterns in the Era of HTML5

@johnwilander

HTML

CSS

HTMLCSS

JavaScript

JavaScript

JavaScript

HTML CSS

Placing legacy web and third party webin iframes allowsthe new code to runwith CSP.

iframe

Page 78: Web Integration Patterns in the Era of HTML5

@johnwilander

main.1-liner.org

HTML

CSS

HTMLCSS

JavaScript

JavaScript

JavaScript

HTML CSS

Then set the sandbox directive without allow-same-origin to leverage the same-origin policy for protection fromvulnerabilities in legacy or third party code.

Sandboxed iframe

main.1-liner.org… or …3rdparty.net

Page 79: Web Integration Patterns in the Era of HTML5

@johnwilander

main.1-liner.org

HTML

CSS

HTMLCSS

JavaScript

JavaScript

JavaScript

HTML CSS

A backwards compatible alternative is to move legacy code to anothersubdomain to leverage the same-origin policy for protection fromvulnerabilities in legacy code.

iframe

legacy.1-liner.org

Page 80: Web Integration Patterns in the Era of HTML5

@johnwilander

new.1-liner.org

HTML

CSS

HTMLCSS

JavaScript

JavaScript

JavaScript

HTML CSS

But beware. Legacy code typically doesn’t relocate gracefully. So you might have to keep its domain and get a new subdomain for your new code.

iframe

main.1-liner.org

Page 81: Web Integration Patterns in the Era of HTML5

@johnwilander

main.1-liner.org

HTML

CSS

HTMLCSS

JavaScript

JavaScript

JavaScript

HTML CSS

Use the postMessage API for communicating between your iframes and your main window.

Sandboxed iframe

main.1-liner.org… or …3rdparty.net

postMessage

Page 82: Web Integration Patterns in the Era of HTML5

@johnwilander

main.1-liner.org

CORS from/to 3rdparty.net

HTML

CSS

HTMLCSS

JavaScript

JavaScript

JavaScript

HTML CSS

Sandboxed iframe

main.1-liner.org… or …3rdparty.net

postMessage

Finally, use CORS when retrieving content from third parties and make sure to encode it right before injecting it to the DOM.

Page 83: Web Integration Patterns in the Era of HTML5

@johnwilander

Thanks!