Please note, this is a STATIC archive of website developer.mozilla.org from 03 Nov 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

Revision 737183 of Same-origin policy

  • Revision slug: Web/Security/Same-origin_policy
  • Revision title: Same-origin policy
  • Revision id: 737183
  • Created:
  • Creator: devurandom
  • Is current revision? No
  • Comment

Revision Content

The same-origin policy restricts how a document or script loaded from one origin can interact with a resource from another origin. Same-origin Policy is used as a means to prevent some of the Cross-site Request Forgery attacks.

Definition of an origin

Two pages have the same origin if the protocol, port (if one is specified), and host are the same for both pages. The following table gives examples of origin comparisons to the URL https://store.company.com/dir/page.html:

URL Outcome Reason
https://store.company.com/dir2/other.html Success  
https://store.company.com/dir/inner/another.html Success  
https://store.company.com/secure.html Failure Different protocol
https://store.company.com:81/dir/etc.html Failure Different port
https://news.company.com/dir/other.html Failure Different host

See also origin definition for file: URLs.

Inherited origins

Content from about:blank, javascript: and data: URLs inherits the origin from the document that loaded the URL, since the URL itself does not give any information about the origin.

IE Exceptions

Internet Explorer has two major exceptions when it comes to same origin policy

  • Trust Zones: if both domains are in highly trusted zone e.g, corporate domains, then the same origin limitations are not applied
  • Port: IE doesn't include port into Same Origin components, therefore https://company.com:81/index.html and https://company.com/index.html are considered from same origin and no restrictions are applied.

These exceptions are non-standard and not supported in any other browser but would be helpful if developing an app for Windows RT (or) IE based web application.

Changing origin

A page may change its own origin with some limitations. A script can set the value of {{domxref("document.domain")}} to a subset of the current domain. If it does so, the shorter domain is used for subsequent origin checks. For example, assume a script in the document at https://store.company.com/dir/other.html executes the following statement:

document.domain = "company.com";

After that statement executes, the page would pass the origin check with https://company.com/dir/page.html. However, by the same reasoning, company.com could not set document.domain to othercompany.com.

The port number is kept separately by the browser. Any call to the setter, 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 that 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 {{domxref("XMLHttpRequest")}} or an {{htmlelement("img")}} element. These interactions are typically placed in three categories:

  • Cross-origin writes are typically allowed. Examples are links, redirects and form submissions. Certain rarely used HTTP requests require preflight.
  • Cross-origin embedding is typically allowed. Examples are listed below.
  • Cross-origin reads are typically not allowed, but read access is often leaked by embedding. For example you can read the width and height 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:

  • JavaScript with <script src="..."></script>. Error messages for syntax errors are only available for same-origin scripts.
  • CSS 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 with {{htmlelement("img")}}. Supported image formats include PNG, JPEG, GIF, BMP, SVG, ...
  • Media files with {{htmlelement("video")}} and {{htmlelement("audio")}}.
  • Plug-ins with <object>, <embed> and <applet>.
  • Fonts with @font-face. Some browsers allow cross-origin fonts, others require same-origin fonts.
  • Anything with <frame> and <iframe>. A site can use the X-Frame-Options header to prevent this form of cross-origin interaction.

How to allow cross-origin access

Use CORS to allow cross-origin access.

How to block cross-origin access

  • To prevent cross-origin writes, check for an unguessable token in the request, known as a Cross-Site Request Forgery (CSRF) token. You must prevent cross-origin reads of pages that know 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 embedding, ensure that your resource can not be interpreted as one of the embeddable formats listed above. The browser does not respect the Content-Type in most cases. 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 such as iframe.contentWindow, {{domxref("window.parent")}}, {{domxref("window.open")}} and {{domxref("window.opener")}} allow documents to directly reference each other. When the two documents do not have the same origin, these references provide very limited access to Window and Location objects, as described in the next two sections.

To communicate further between documents from different origins, use {{domxref("window.postMessage")}}.

Window

Specification:  https://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#security-window.

The following cross-origin access to Window properties is allowed:

Methods
{{domxref("window.blur")}}
{{domxref("window.close")}}
{{domxref("window.focus")}}
{{domxref("window.postMessage")}}
Attributes  
{{domxref("window.closed")}} Read only.
{{domxref("window.frames")}} Read only.
{{domxref("window.length")}} Read only.
{{domxref("window.location")}} Read/write.
{{domxref("window.opener")}} Read only.
{{domxref("window.parent")}} Read only.
{{domxref("window.self")}} Read only.
{{domxref("window.top")}} Read only.
{{domxref("window.window")}} Read only.

Some browsers allow access to more properties than the specification allows.

Location

Specification:  https://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#security-location.

The following cross-origin access to Location properties is allowed:

Methods
{{domxref("location.replace")}}
Attributes  
{{domxref("URLUtils.href")}} Write only.

Some browsers allow access to more properties than the specification allows.

Cross-origin data storage access

Access to data stored in the browser such as localStorage and IndexedDB are 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.

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.

See also

Original Document Information

  • Author(s): Jesse Ruderman

 

Revision Source

<p>The same-origin policy restricts how a document or script loaded from one origin can interact with a resource from another origin. Same-origin Policy is used as a means to prevent some of the Cross-site Request Forgery attacks.</p>

<h2 id="Definition_of_an_origin">Definition of an origin</h2>

<p>Two pages have the same origin if the protocol, port (if one is specified), and host are the same for both pages. The following table gives examples of origin comparisons to the URL <code>https://store.company.com/dir/page.html</code>:</p>

<table class="standard-table">
 <tbody>
  <tr>
   <th>URL</th>
   <th>Outcome</th>
   <th>Reason</th>
  </tr>
  <tr>
   <td><code>https://store.company.com/dir2/other.html</code></td>
   <td>Success</td>
   <td>&nbsp;</td>
  </tr>
  <tr>
   <td><code>https://store.company.com/dir/inner/another.html</code></td>
   <td>Success</td>
   <td>&nbsp;</td>
  </tr>
  <tr>
   <td><code>https://store.company.com/secure.html</code></td>
   <td>Failure</td>
   <td>Different protocol</td>
  </tr>
  <tr>
   <td><code>https://store.company.com:81/dir/etc.html</code></td>
   <td>Failure</td>
   <td>Different port</td>
  </tr>
  <tr>
   <td><code>https://news.company.com/dir/other.html</code></td>
   <td>Failure</td>
   <td>Different host</td>
  </tr>
 </tbody>
</table>

<p>See also <a href="/en-US/docs/Same-origin_policy_for_file:_URIs" title="Same-origin_policy_for_file:_URIs">origin definition for <code>file:</code> URLs</a>.</p>

<h3 id="Inherited_origins">Inherited origins</h3>

<p>Content from <code>about:blank</code>, <code>javascript:</code> and <code>data:</code> URLs inherits the origin from the document that loaded the URL, since the URL itself does not give any information about the origin.</p>

<h3 id="IE_Exceptions" style="line-height: 30px;">IE Exceptions</h3>

<p>Internet Explorer has two major exceptions when it comes to same origin policy</p>

<ul>
 <li>Trust Zones: if both domains are in highly trusted zone e.g, corporate domains, then the same origin limitations are not applied</li>
 <li>Port: IE doesn't include port into Same Origin components, therefore&nbsp;<span style="font-family: 'Courier New', 'Andale Mono', monospace; font-size: 12px; line-height: normal; background-color: rgba(212, 221, 228, 0.14902);">https://company.com:81/index.html&nbsp;<span style="font-family: 'Open Sans', sans-serif; line-height: 21px; background-color: rgb(255, 255, 255);">and&nbsp;</span></span><span style="font-family: 'Courier New', 'Andale Mono', monospace; font-size: 12px; line-height: normal; background-color: rgba(212, 221, 228, 0.14902);">https://company.com/index.html&nbsp;</span>are considered from same origin and no restrictions are applied.</li>
</ul>

<p>These exceptions are non-standard and not supported in any other browser but would be helpful if developing an app for Windows RT (or) IE based web application.</p>

<h2 id="Changing_origin">Changing origin</h2>

<p>A page may change its own origin with some limitations. A script can set the value of {{domxref("document.domain")}} to a subset of the current domain. If it does so, the shorter domain is used for subsequent origin checks. For example, assume a script in the document at <code>https://store.company.com/dir/other.html</code> executes the following statement:</p>

<pre>
document.domain = "company.com";
</pre>

<p>After that statement executes, the page would pass the origin check with <code>https://company.com/dir/page.html</code>. However, by the same reasoning, <code>company.com</code> could <strong>not</strong> set <code>document.domain</code> to <code>othercompany.com</code>.</p>

<p>The port number is kept separately by the browser. Any call to the setter, including <code>document.domain = document.domain</code> causes the port number to be overwritten with <code>null</code>. Therefore one <strong>cannot</strong> make <code>company.com:8080</code> talk to <code>company.com</code> by only setting <code>document.domain = "company.com"</code> in the first. It has to be set in both so that port numbers are both <code>null</code>.</p>

<div class="note">
<p><strong>Note:</strong> When using <code>document.domain</code> to allow a subdomain to access its parent securely, you need to set <code>document.domain</code> 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.</p>
</div>

<h2 id="Cross-origin_network_access">Cross-origin network access</h2>

<p>The same-origin policy controls interactions between two different origins, such as when you use {{domxref("XMLHttpRequest")}} or an&nbsp;{{htmlelement("img")}} element. These interactions are typically placed in three categories:</p>

<ul>
 <li>Cross-origin <em>writes </em>are typically allowed. Examples are links, redirects and form submissions. Certain rarely used HTTP requests require <a href="/en-US/docs/HTTP/Access_control_CORS#Preflighted_requests" title="HTTP/Access_control_CORS#Preflighted_requests">preflight</a>.</li>
 <li>Cross-origin <em>embedding </em>is typically allowed. Examples are listed below.</li>
 <li>Cross-origin <em>reads </em>are typically not allowed, but read access is often leaked by embedding. For example you can read the width and height of an embedded image, the actions of an embedded script, or the <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=629094" title="https://grepular.com/Abusing_HTTP_Status_Codes_to_Expose_Private_Information">availability of an embedded resource</a>.</li>
</ul>

<p>Here are some examples of resources which may be embedded cross-origin:</p>

<ul>
 <li>JavaScript with <code>&lt;script src="..."&gt;&lt;/script&gt;</code>. Error messages for syntax errors are only available for same-origin scripts.</li>
 <li>CSS with <code>&lt;link rel="stylesheet" href="..."&gt;</code>. Due to the <a href="https://scarybeastsecurity.blogspot.dk/2009/12/generic-cross-browser-cross-domain.html" title="https://scarybeastsecurity.blogspot.dk/2009/12/generic-cross-browser-cross-domain.html">relaxed syntax rules</a> of CSS, cross-origin CSS requires a correct <code>Content-Type</code> header. Restrictions vary by browser: <a href="https://msdn.microsoft.com/en-us/library/ie/gg622939%28v=vs.85%29.aspx" title="https://msdn.microsoft.com/en-us/library/ie/gg622939%28v=vs.85%29.aspx">IE</a>, <a href="https://www.mozilla.org/security/announce/2010/mfsa2010-46.html" title="https://www.mozilla.org/security/announce/2010/mfsa2010-46.html">Firefox</a>, <a href="https://code.google.com/p/chromium/issues/detail?id=9877" title="https://code.google.com/p/chromium/issues/detail?id=9877">Chrome</a>, <a href="https://support.apple.com/kb/HT4070" title="https://support.apple.com/kb/HT4070">Safari</a> (scroll down to CVE-2010-0051) and <a href="https://www.opera.com/support/kb/view/943/" title="https://www.opera.com/support/kb/view/943/">Opera</a>.</li>
 <li>Images with {{htmlelement("img")}}. Supported image formats include PNG, JPEG, GIF, BMP, SVG, ...</li>
 <li>Media files with {{htmlelement("video")}} and {{htmlelement("audio")}}.</li>
 <li>Plug-ins with <a href="/en-US/docs/HTML/Element/object" title="HTML/Element/object"><code>&lt;object&gt;</code></a>, <a href="/en-US/docs/HTML/Element/embed" title="HTML/Element/embed"><code>&lt;embed&gt;</code></a> and <a href="/en-US/docs/HTML/Element/applet" title="HTML/Element/applet"><code>&lt;applet&gt;</code></a>.</li>
 <li>Fonts with <a href="/en-US/docs/CSS/@font-face" title="CSS/@font-face"><code>@font-face</code></a>. Some browsers allow cross-origin fonts, others require same-origin fonts.</li>
 <li>Anything with <a href="/en-US/docs/HTML/Element/frame" title="HTML/Element/frame"><code>&lt;frame&gt;</code></a> and <a href="/en-US/docs/HTML/Element/iframe" title="HTML/Element/iframe"><code>&lt;iframe&gt;</code></a>. A site can use the <code><a href="/en-US/docs/HTTP/X-Frame-Options" title="HTTP/X-Frame-Options">X-Frame-Options</a></code> header to prevent this form of cross-origin interaction.</li>
</ul>

<h3 id="How_to_allow_cross-origin_access">How to allow cross-origin access</h3>

<p>Use <a href="/en-US/docs/HTTP/Access_control_CORS" title="HTTP/Access_control_CORS">CORS</a> to allow cross-origin access.</p>

<h3 id="How_to_block_cross-origin_access">How to block cross-origin access</h3>

<ul>
 <li>To prevent cross-origin writes, check for an unguessable token in the request, known as a <a href="https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29" title="https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29">Cross-Site Request Forgery (CSRF)</a> token. You must prevent cross-origin reads of pages that know this token.</li>
 <li>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.</li>
 <li>To prevent cross-origin embedding, ensure that your resource can not be interpreted as one of the embeddable formats listed above. The browser does not respect the <code>Content-Type</code> in most cases. For example if you point a <code>&lt;script&gt;</code> 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.</li>
</ul>

<h2 id="Cross-origin_script_API_access">Cross-origin script API access</h2>

<p>JavaScript APIs such as <a href="/en-US/docs/DOM/HTMLIFrameElement" title="DOM/HTMLIFrameElement"><code>iframe.contentWindow</code></a>, {{domxref("window.parent")}}, {{domxref("window.open")}} and {{domxref("window.opener")}} allow documents to directly reference each other. When the two documents do not have the same origin, these references provide very limited access to <a href="/en-US/docs/Web/API/Window"><code>Window</code></a> and <a href="/en-US/docs/Web/API/Location"><code>Location</code></a> objects, as described in the next two sections.</p>

<p>To communicate further between documents from different origins, use {{domxref("window.postMessage")}}.</p>

<h3 id="Window">Window</h3>

<p>Specification:&nbsp; <a href="https://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#security-window">https://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#security-window</a>.</p>

<p>The following cross-origin access to <code>Window</code> properties is allowed:</p>

<table class="standard-table fullwidth-table">
 <thead>
  <tr>
   <th scope="col">Methods</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>{{domxref("window.blur")}}</td>
  </tr>
  <tr>
   <td>{{domxref("window.close")}}</td>
  </tr>
  <tr>
   <td>{{domxref("window.focus")}}</td>
  </tr>
  <tr>
   <td>{{domxref("window.postMessage")}}</td>
  </tr>
 </tbody>
</table>

<table class="standard-table fullwidth-table">
 <thead>
  <tr>
   <th scope="col">Attributes</th>
   <th scope="col">&nbsp;</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>{{domxref("window.closed")}}</td>
   <td>Read only.</td>
  </tr>
  <tr>
   <td>{{domxref("window.frames")}}</td>
   <td>Read only.</td>
  </tr>
  <tr>
   <td>{{domxref("window.length")}}</td>
   <td>Read only.</td>
  </tr>
  <tr>
   <td>{{domxref("window.location")}}</td>
   <td>Read/write.</td>
  </tr>
  <tr>
   <td>{{domxref("window.opener")}}</td>
   <td>Read only.</td>
  </tr>
  <tr>
   <td>{{domxref("window.parent")}}</td>
   <td>Read only.</td>
  </tr>
  <tr>
   <td>{{domxref("window.self")}}</td>
   <td>Read only.</td>
  </tr>
  <tr>
   <td>{{domxref("window.top")}}</td>
   <td>Read only.</td>
  </tr>
  <tr>
   <td>{{domxref("window.window")}}</td>
   <td>Read only.</td>
  </tr>
 </tbody>
</table>

<p>Some browsers allow access to more properties than the specification allows.</p>

<h3 id="Location">Location</h3>

<p>Specification:&nbsp; <a href="https://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#security-location">https://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#security-location</a>.</p>

<p>The following cross-origin access to <code>Location</code> properties is allowed:</p>

<table class="standard-table fullwidth-table">
 <thead>
  <tr>
   <th scope="col">Methods</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>{{domxref("location.replace")}}</td>
  </tr>
 </tbody>
</table>

<table class="standard-table fullwidth-table">
 <thead>
  <tr>
   <th scope="col">Attributes</th>
   <th scope="col">&nbsp;</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>{{domxref("URLUtils.href")}}</td>
   <td>Write only.</td>
  </tr>
 </tbody>
</table>

<p>Some browsers allow access to more properties than the specification allows.</p>

<h2 id="Cross-origin_data_storage_access">Cross-origin data storage access</h2>

<p>Access to data stored in the browser such as <a href="/en-US/docs/Web/Guide/API/DOM/Storage">localStorage</a> and <a href="/en-US/docs/IndexedDB">IndexedDB</a> are 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.</p>

<p>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 <a href="https://publicsuffix.org/">Public Suffix List</a> 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.</p>

<h2 id="See_also">See also</h2>

<ul>
 <li><a href="/en-US/docs/Same-origin_policy_for_file:_URIs" title="Same-origin policy for file: URIs">Same-origin policy for file: URIs</a></li>
 <li><a href="https://www.w3.org/Security/wiki/Same_Origin_Policy" title="https://www.w3.org/Security/wiki/Same_Origin_Policy">Same-Origin Policy at W3C</a></li>
</ul>

<div class="originaldocinfo">
<h2 id="Original_Document_Information" name="Original_Document_Information">Original Document Information</h2>

<ul>
 <li>Author(s): Jesse Ruderman</li>
</ul>
</div>

<p>&nbsp;</p>
Revert to this revision