Cross Domain and Browser Security
Erlend Oftedal
—
@webtonull
OWASP Göteborg
Erlend Oftedal
—
@webtonull
OWASP Göteborg
$.get("http://domain-b.com/", function(data) { ... });
Setting up a local proxy on the web server:
$.get("http://domain-a.com/proxy?url=http://domain-b.com", function(data) { ... } );
c.example.com
can join the partyframeElement
window.opener
window.name
<script>
-tag:
<script> function setData(data) { //handle data } </script> <script src="http://domain-b.com/data"></script>
setData({"some":"data", ...});
<script> function setData(data) { stealData(data); } </script> <script src="http://domain-b.com/data"></script>
ExternalInterface.call("setData", data);
<?xml version="1.0" encoding="UTF-8"?> <cross-domain-policy> <allow-access-from domain="domain-a.com" /> </cross-domain-policy>
<?xml version="1.0" encoding="UTF-8"?> <cross-domain-policy> <allow-access-from domain="*" /> </cross-domain-policy>
Allows any flash on any web site to read data on behalf of the current user!
Alexa top 100 local domains:
27 | |
30 | |
31 |
Only works with insecure (open) crossdomain.xmls... sigh...
HtmlPage.Window.Invoke("setData", data);
var targetFrame = document.getElementById("theIframe").contentWindow; targetFrame.postMessage(data, "http://domain-b.com");
if (window.addEventListener) { window.addEventListener("message", receiveMessage, false); } else { window.attachEvent("onmessage", receiveMessage); } function receiveMessage(event) { if (event.origin !== "http://domain-a.com") { //IMPORTANT: always check origin return; } // handle message }
*
as target for messagesAccess-control-*
application/x-www-form-urlencoded
, multipart/form-data
, or text/plain
GET http://domain-b.com/some/resource ...
200 OK Access-Control-Allow-Origin: http://domain-a.com ...
OPTIONS http://domain-b.com/some/resource ...
200 OK Access-Control-Allow-Origin: http://domain-a.com ...
POST http://domain-b.com/some/resource Content-Type: application/json ...
200 OK Access-Control-Allow-Origin: http://domain-a.com ...
Access-Control-Request-Method: POST
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Request-Headers: X-PINGOTHER
Access-Control-Allow-Headers: X-PINGOTHER
Access-Control-Max-Age: 1728000
Access-Control-Allow-Credentials: true
Access-control-allow-origin: *
Access-control-allow-credentials: true
function fileUpload(url, fileData, fileName) { var fileSize = fileData.length, boundary = "xxxxxxxxx", xhr = new XMLHttpRequest(); xhr.open("POST", url, true); xhr.setRequestHeader("Content-Type", "multipart/form-data, boundary="+boundary); xhr.setRequestHeader("Content-Length", fileSize); var body = "--" + boundary + "\r\n"; body += 'Content-Disposition: form-data; name="contents";" + "filename="' + fileName + '"\r\n'; body += "Content-Type: application/octet-stream\r\n\r\n"; body += fileData + "\r\n"; body += "--" + boundary + "--"; xhr.send(body); }
Access-control-allow-origin
-headervar xdr = new XDomainRequest(); xdr.open("get", "http://domain-b.com/some/resource"); xdr.send();
Content-Security-Policy
<meta http-equiv="Content-Security-Policy" content="">
X-Content-Security-Policy
X-Webkit-CSP
Content-Security-Policy: default-src *; script-src 'self' *.google.com https://www.owasp.org:443
default-src
- the defaultscript-src
- javascriptobject-src
- flash, java etc.style-src
- stylesheets (CSS)img-src
- picturesmedia-src
- video and audioframe-src
- iframesfont-src
- fontsconnect-src
- websockets, xhr-requests'self'
- same origin as website'none'
- no sources allowed'unsafe-inline'
style-src
and script-src
'unsafe-eval'
script-src
eval()
,setTimeout()
and Function()
'unsafe-inline'
and 'unsafe-eval'
++ does not workContent-Security-Policy
but no browser yet supports itreport-uri
- this directive instructs browser to send a json report when content conflicts with the given CSPX-Content-Security-Policy-Report-Only
- no actual blocking - just reportingStrict-Transport-Security: max-age=14400
Strict-Transport-Security: max-age=14400; includeSubDomains
X-Frame-Options: deny
X-Frame-Options: sameorigin
X-Frame-Options: allow-from http://erlend.oftedal.no
<iframe sandbox src="..." ></iframe>
<iframe sandbox="allow-scripts" src="..." ></iframe>
Sandbox
-directives:
Allow-scripts
Allow-sameorigin
Allow-top-navigation
Allow-forms
<iframe security="restricted" src="..." ></iframe>
X-Content-Type-Options: nosniff
http://www.google.com/search?q=<script>
Questions?
Demo:
Access-Control-Allow-Origin: *