The same-origin policy is a critical security mechanism that restricts how a document or script loaded from one origin can interact with a resource from another origin. It helps isolate potentially malicious documents, reducing possible attack vectors.
Definition of an origin
Two URLs have the same origin if the protocol, port (if specified), and host are the same for both. You may see this referenced as the “scheme/host/port tuple”, or just “tuple”. (A “tuple” is a set of items that together comprise a whole — a generic form for double/triple/quadruple/quintuple/etc.)
The following table gives examples of origin comparisons with the URL http://store.company.com/dir/page.html:
|http://store.company.com/dir2/other.html||Same origin||Only the path differs|
|http://store.company.com/dir/inner/another.html||Same origin||Only the path differs|
|http://store.company.com:81/dir/page.html||Failure||Different port (http:// is port 80 by default)|
See also origin definition for file: URLs, because their comparison is more complicated.
data: URLs get a new, empty, security context.
Exceptions in Internet Explorer
Internet Explorer has two major exceptions to the same-origin policy:
If both domains are in the highly trusted zone (e.g. corporate intranet domains), then the same-origin limitations are not applied.
IE doesn’t include port into same-origin checks. Therefore, https://company.com:81/index.html and https://company.com/index.html are considered the same origin and no restrictions are applied.
These exceptions are nonstandard and unsupported in any other browser.
A page may change its own origin, with some limitations. A script can set the value of document.domain to its current domain or a superdomain of its current domain. If set to a superdomain of the current domain, the shorter superdomain is used for same-origin checks.
For example, assume a script from the document at http://store.company.com/dir/other.html executes the following:
document.domain = “company.com”;
Afterward, the page can pass the same-origin check with http://company.com/dir/page.html (assuming http://company.com/dir/page.html sets its document.domain to “company.com” to indicate that it wishes to allow that – see document.domain for more). However, company.com could not set document.domain to othercompany.com, since that is not a superdomain of company.com.
The port number is checked separately by the browser. Any call to document.domain, including document.domain = document.domain, causes the port number to be overwritten with null. Therefore, one cannot make company.com:8080 talk to company.com by only setting document.domain = “company.com” in the first. It has to be set in both so their port numbers are both null.
Note: When using document.domain to allow a subdomain to access its parent securely, you need to set document.domain to the same value in both the parent domain and the subdomain. This is necessary even if doing so is simply setting the parent domain back to its original value. Failure to do this may result in permission errors.
Cross-origin network access
The same-origin policy controls interactions between two different origins, such as when you use XMLHttpRequest or an element embeds an image into the document. It is a replaced element.”><img> element. These interactions are typically placed into three categories:
- Cross-origin writes are typically allowed. Examples are links, redirects, and form submissions. Some HTTP requests require preflight.
- Cross-origin embedding is typically allowed. (Examples are listed below.)
- Cross-origin reads are typically disallowed, but read access is often leaked by embedding. For example, you can read the dimensions of an embedded image, the actions of an embedded script, or the availability of an embedded resource.
Here are some examples of resources which may be embedded cross-origin:
- CSS applied with <link rel=”stylesheet” href=”…”>. Due to the relaxed syntax rules of CSS, cross-origin CSS requires a correct Content-Type header. Restrictions vary by browser: IE, Firefox, Chrome, Safari (scroll down to CVE-2010-0051) and Opera.
- Images displayed by element embeds an image into the document. It is a replaced element.”><img>.
- Media played by ) embeds a media player which supports video playback into the document.”><video> and element is used to embed sound content in documents. It may contain one or more audio sources, represented using the src attribute or the <source> element: the browser will choose the most suitable one. It can also be the destination for streamed media, using a MediaStream.”><audio>.
- Plugins embedded with element represents an external resource, which can be treated as an image, a nested browsing context, or a resource to be handled by a plugin.”><object>, element embeds external content at the specified point in the document. This content is provided by an external application or other source of interactive content such as a browser plug-in.”><embed>, and ) embeds a Java applet into the document; this element has been deprecated in favor of <object>.”><applet>.
- Fonts applied with @font-face. Some browsers allow cross-origin fonts, others require same-origin.
- Anything embedded by is an HTML element which defines a particular area in which another HTML document can be displayed. A frame should be used within a <frameset>.”><frame> and ) represents a nested browsing context, embedding another HTML page into the current one.”><iframe>. Sites can use the , <iframe>, <embed> or <object> . Sites can use this to avoid clickjacking attacks, by ensuring that their content is not embedded into other sites.”>X-Frame-Options header to prevent cross-origin framing.
How to allow cross-origin access
How to block cross-origin access
- To prevent cross-origin writes, check an unguessable token in the request — known as a Cross-Site Request Forgery (CSRF) token. You must prevent cross-origin reads of pages that require this token.
- To prevent cross-origin reads of a resource, ensure that it is not embeddable. It is often necessary to prevent embedding because embedding a resource always leaks some information about it.
Cross-origin script API access
To communicate between documents from different origins, use window.postMessage.
Specification: HTML Living Standard § Cross-origin objects.
The following cross-origin access to these Window properties is allowed:
Some browsers allow access to more properties than the above.
The following cross-origin access to Location properties is allowed:
Some browsers allow access to more properties than the above.
Cross-origin data storage access
Cookies use a separate definition of origins. A page can set a cookie for its own domain or any parent domain, as long as the parent domain is not a public suffix. Firefox and Chrome use the Public Suffix List to determine if a domain is a public suffix. Internet Explorer uses its own internal method to determine if a domain is a public suffix. The browser will make a cookie available to the given domain including any sub-domains, no matter which protocol (HTTP/HTTPS) or port is used. When you set a cookie, you can limit its availability using the Domain, Path, Secure and Http-Only flags. When you read a cookie, you cannot see from where it was set. Even if you use only secure https connections, any cookie you see may have been set using an insecure connection.
Original Document Information
- Author(s): Jesse Ruderman