Same-origin access control – how to implement it and why it matters
First, some background.
On the web, a cookie is a name-value pair that is sent from a web site to a browser, stored, and sent back on subsequent requests to the same web site. If you’re in Europe (or even if you’re not), you’ve probably seen the endless notices on web sites advising you that cookies might be used for targeted advertising – but they also have other, more benign uses. Notably, they’re often used in authentication. When you log in to a web site, it gives you a cookie with a unique value by which it can recognize you on subsequent requests, so that you don’t have to log in again with every click.
Cookies work for tracking and targeted advertising because they can be sent with almost any request to a web site – not just requests that the user makes explicitly. For example, a page might be hosted on https://www.example.com/ but might also load some scripts from a content delivery network (CDN), fonts from a font service, and advertising from an ad network, each with their own domain names. If the user already has cookies from those domains, the browser will (by default) send the cookies back with those requests. The responses can also set new cookies for their respective domains. If different sites use the same ad network (or CDN etc.) then users can be re-identified and tracked across those sites.
Cross-site request forgery
Cross-Origin Resource Sharing
Content Security Policy’s sandbox directive
CSP works by specifying an HTTP header, Content-Security-Policy, that can be used to specify directives that instruct the browser to place certain restrictions on a page. One such directive is sandbox. This directive allows you to restrict the current page as if it were being loaded in an <iframe> with the sandbox attribute. This enforces a number of limitations which can then be lifted individually – for example, the page can’t run any scripts (unless you say so), it can’t display pop-up windows… and it can’t make same-origin requests. That is: any requests it makes will be treated as cross-origin, even if they’re actually requests to what would otherwise be considered the same origin.
This could be useful if you want to build apps that use your API and host them on the same domain as the API and other parts of your web site, but still want them to be subject to the same security restrictions as apps running on third-party domains.
This even works in Internet Explorer. IE doesn’t support most of the CSP standard, but it does support the sandbox directive, at least in some versions. However, it expects the HTTP header to be named X-Content-Security-Policy rather than the standard Content-Security-Policy, so you need to specify both.
Of course, it’s still possible that some users might be using very old versions of IE, or other browsers that don’t support CSP (though there aren’t too many left); so this shouldn’t be considered a strong security control suitable for use with entirely untrusted code, but it could serve well as a defence-in-depth measure.