Same-origin policy

Thesame-origin policyis a critical security mechanism that restricts how a document or script loaded by oneorigincan interact with a resource from another origin.

It helps isolate potentially malicious documents, reducing possible attack vectors. For example, it prevents a malicious website on the Internet from running JS in a browser to read data from a third-party webmail service (which the user is signed into) or a company intranet (which is protected from direct access by the attacker by not having a public IP address) and relaying that data to the attacker.

Definition of an origin

Two URLs have thesame originif theprotocol,port(if specified), andhostare 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 URLhttp://store.company.com/dir/page.html:

URL Outcome Reason
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
https://store.company.com/page.html Failure Different protocol
http://store.company.com:81/dir/page.html Failure Different port (http://is port 80 by default)
http://news.company.com/dir/page.html Failure Different host

Inherited origins

Scripts executed from pages with anabout:blankorjavascript:URL inherit the origin of the document containing that URL, since these types of URLs do not contain information about an origin server.

For example,about:blankis often used as a URL of new, empty popup windows into which the parent script writes content (e.g. via theWindow.open()mechanism). If this popup also contains JavaScript, that script would inherit the same origin as the script that created it.

data:URLs get a new, empty, security context.

File origins

Modern browsers usually treat the origin of files loaded using thefile:///schema asopaque origins. What this means is that if a file includes other files from the same folder (say), they are not assumed to come from the same origin, and may triggerCORSerrors.

Note that theURL specificationstates that the origin of files is implementation-dependent, and some browsers may treat files in the same directory or subdirectory as same-origin even though this hassecurity implications.

Changing origin

Warning:The approach described here (using thedocument.domainsetter) is deprecated because it undermines the security protections provided by the same origin policy, and complicates the origin model in browsers, leading to interoperability problems and security bugs.

A page may change its own origin, with some limitations. A script can set the value ofdocument.domainto 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 athttp://store.company.com/dir/other.htmlexecutes the following:

js
document.domain="company.com";

Afterward, the page can pass the same-origin check withhttp://company.com/dir/page.html(assuminghttp://company.com/dir/page.htmlsets itsdocument.domainto "company.com"to indicate that it wishes to allow that - seedocument.domainfor more). However,company.comcouldnotsetdocument.domaintoothercompany.com,since that is not a superdomain ofcompany.com.

The port number is checked separately by the browser. Any call todocument.domain,includingdocument.domain = document.domain,causes the port number to be overwritten withnull.Therefore, onecannotmakecompany.com:8080talk tocompany.comby only settingdocument.domain = "company.com"in the first. It has to be set in both so their port numbers are bothnull.

The mechanism has some limitations. For example, it will throw a "SecurityError"DOMExceptionif thedocument-domainPermissions-Policyis enabled or the document is in a sandboxed<iframe>,and changing the origin in this way does not affect the origin checks used by many Web APIs (e.g.localStorage,indexedDB,BroadcastChannel,SharedWorker). A more exhaustive list of failure cases can be found inDocument.domain > Failures.

Note:When usingdocument.domainto allow a subdomain to access its parent, you need to setdocument.domainto thesame valuein both the parent domain and the subdomain. This is necessary even if doing so is 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 usefetch()or an<img>element. These interactions are typically placed into three categories:

  • Cross-originwritesare typically allowed. Examples are links, redirects, and form submissions. Some HTTP requests requirepreflight.
  • Cross-originembeddingis typically allowed. (Examples are listed below.)
  • Cross-originreadsare 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 theavailability of an embedded resource.

Here are some examples of resources which may be embedded cross-origin:

  • JavaScript with<script src= "…" ></script>.Error details for syntax errors are only available for same-origin scripts.
  • CSS applied with<link rel= "stylesheet" href= "…" >.Due to the relaxed syntax rules of CSS, cross-origin CSS requires a correctContent-Typeheader. Browsers block stylesheet loads if it is a cross-origin load where the MIME type is incorrect and the resource does not start with a valid CSS construct.
  • Images displayed by<img>.
  • Media played by<video>and<audio>.
  • External resources embedded with<object>and<embed>.
  • Fonts applied with@font-face.Some browsers allow cross-origin fonts, others require same-origin.
  • Anything embedded by<iframe>.Sites can use theX-Frame-Optionsheader to prevent cross-origin framing.

How to allow cross-origin access

UseCORSto allow cross-origin access. CORS is a part ofHTTPthat lets servers specify any other hosts from which a browser should permit loading of content.

How to block cross-origin access

  • To prevent cross-origin writes, check an unguessable token in the request — known as aCross-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.
  • To prevent cross-origin embeds, ensure that your resource cannot be interpreted as one of the embeddable formats listed above. Browsers may not respect theContent-Typeheader. For example, if you point a<script>tag at an HTML document, the browser will try to parse the HTML as JavaScript. When your resource is not an entry point to your site, you can also use a CSRF token to prevent embedding.

Cross-origin script API access

JavaScript APIs likeiframe.contentWindow,window.parent,window.open,andwindow.openerallow documents to directly reference each other. When two documents do not have the same origin, these references provide very limited access toWindowandLocationobjects, as described in the next two sections.

To communicate between documents from different origins, usewindow.postMessage.

Specification:HTML Living Standard § Cross-origin objects.

Window

The following cross-origin access to theseWindowproperties is allowed:

Methods
window.blur
window.close
window.focus
window.postMessage
Attributes
window.closed Read only.
window.frames Read only.
window.length Read only.
window.location Read/Write.
window.opener Read only.
window.parent Read only.
window.self Read only.
window.top Read only.
window.window Read only.

Some browsers allow access to more properties than the above.

Location

The following cross-origin access toLocationproperties is allowed:

Methods
location.replace
Attributes
location.href Write-only.

Some browsers allow access to more properties than the above.

Cross-origin data storage access

Access to data stored in the browser such asWeb StorageandIndexedDBare separated by origin. Each origin gets its own separate storage, and JavaScript in one origin cannot read from or write to the storage belonging to another origin.

Cookiesuse 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 thePublic Suffix Listto determine if a domain is a public suffix. When you set a cookie, you can limit its availability using theDomain,Path,Secure,andHttpOnlyflags. 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.

See also