aboutsummaryrefslogtreecommitdiff
path: root/files/zh-cn/web/security/same-origin_policy/index.html
diff options
context:
space:
mode:
authorPeter Bengtsson <mail@peterbe.com>2020-12-08 14:40:17 -0500
committerPeter Bengtsson <mail@peterbe.com>2020-12-08 14:40:17 -0500
commit33058f2b292b3a581333bdfb21b8f671898c5060 (patch)
tree51c3e392513ec574331b2d3f85c394445ea803c6 /files/zh-cn/web/security/same-origin_policy/index.html
parent8b66d724f7caf0157093fb09cfec8fbd0c6ad50a (diff)
downloadtranslated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.gz
translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.bz2
translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.zip
initial commit
Diffstat (limited to 'files/zh-cn/web/security/same-origin_policy/index.html')
-rw-r--r--files/zh-cn/web/security/same-origin_policy/index.html272
1 files changed, 272 insertions, 0 deletions
diff --git a/files/zh-cn/web/security/same-origin_policy/index.html b/files/zh-cn/web/security/same-origin_policy/index.html
new file mode 100644
index 0000000000..56b8d35992
--- /dev/null
+++ b/files/zh-cn/web/security/same-origin_policy/index.html
@@ -0,0 +1,272 @@
+---
+title: 浏览器的同源策略
+slug: Web/Security/Same-origin_policy
+tags:
+ - AJAX
+ - CORS
+ - JavaScript
+ - Same-origin policy
+ - Security
+ - 同源策略
+translation_of: Web/Security/Same-origin_policy
+---
+<p><strong>同源策略</strong>是一个重要的安全策略,它用于限制一个{{Glossary("origin")}}的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。</p>
+
+<h2 id="同源的定义"><strong>同源</strong>的<strong>定义</strong></h2>
+
+<p>如果两个 URL 的 {{Glossary("protocol")}}、{{Glossary("port")}} (如果有指定的话)和 {{Glossary("host")}} 都相同的话,则这两个 URL 是<em>同源</em>。这个方案也被称为“协议/主机/端口元组”,或者直接是 “元组”。(“元组” 是指一组项目构成的整体,双重/三重/四重/五重/等的通用形式)。</p>
+
+<p>下表给出了与 URL <code><span class="nowiki">http://store.company.com/dir/page.html</span></code> 的源进行对比的示例:</p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th>URL</th>
+ <th>结果</th>
+ <th>原因</th>
+ </tr>
+ <tr>
+ <td><code><span class="nowiki">http://store.company.com/dir2/other.html</span></code></td>
+ <td>同源</td>
+ <td><font face="consolas, Liberation Mono, courier, monospace">只有路径不同</font></td>
+ </tr>
+ <tr>
+ <td><code><span class="nowiki">http://store.company.com/dir/inner/another.html</span></code></td>
+ <td>同源</td>
+ <td><font face="consolas, Liberation Mono, courier, monospace">只有路径不同</font></td>
+ </tr>
+ <tr>
+ <td><code><span class="nowiki">https://store.company.com/secure.html</span></code></td>
+ <td>失败</td>
+ <td>协议不同</td>
+ </tr>
+ <tr>
+ <td><code><span class="nowiki">http://store.company.com:81/dir/etc.html</span></code></td>
+ <td>失败</td>
+ <td>端口不同 ( <code>http://</code> 默认端口是80)</td>
+ </tr>
+ <tr>
+ <td><code><span class="nowiki">http://news.company.com/dir/other.html</span></code></td>
+ <td>失败</td>
+ <td>主机不同</td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id="源的继承"><strong>源的</strong><strong>继承</strong></h3>
+
+<p>在页面中通过 <code>about:blank</code> 或 <code>javascript:</code> URL 执行的脚本会继承打开该 URL 的文档的源,因为这些类型的 URLs 没有包含源服务器的相关信息。</p>
+
+<div class="blockIndicator note">
+<p>例如,<code>about:blank</code> 通常作为父脚本写入内容的新的空白弹出窗口的 URL(例如,通过  <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/open">Window.open()</a>  )。 如果此弹出窗口也包含 JavaScript,则该脚本将从创建它的脚本那里继承对应的源。</p>
+</div>
+
+<div class="note">
+<p>注意:在{{Gecko("6.0")}}之前,如果用户在位置栏中输入 <code>data</code> URLs,<code>data</code> URLs 将继承当前浏览器窗口中网页的安全上下文。</p>
+</div>
+
+<div class="blockIndicator warning">
+<p><code>data</code>:URLs 获得一个新的,空的安全上下文。</p>
+</div>
+
+<h3 id="IE_中的特例"><strong>IE 中的特例</strong></h3>
+
+<p>Internet Explorer 的同源策略有两个主要的差异点:</p>
+
+<ul>
+ <li><strong>授信范围</strong>(Trust Zones):两个相互之间高度互信的域名,如公司域名(corporate domains),则不受同源策略限制。</li>
+ <li><strong>端口</strong>:IE 未将端口号纳入到同源策略的检查中,因此<span> </span><span><code>https://company.com:81/index.html</code> </span><span>和 </span><span><code>https://company.com/index.html</code>  </span>属于同源并且不受任何限制。</li>
+</ul>
+
+<p>这些差异点是不规范的,其它浏览器也未做出支持,但会助于开发基于window RT IE的应用程序。</p>
+
+<h2 id="源的更改"><strong>源</strong>的更改</h2>
+
+<p>满足某些限制条件的情况下,页面是可以修改它的源。脚本可以将 {{domxref("document.domain")}} 的值设置为其当前域或其当前域的父域。如果将其设置为其当前域的父域,则这个较短的父域将用于后续源检查。</p>
+
+<p>例如:假设 http://store.company.com/dir/other.html 文档中的一个脚本执行以下语句:</p>
+
+<pre class="eval">document.domain = "company.com";
+</pre>
+
+<p>这条语句执行之后,页面将会成功地通过与 <code><span class="nowiki">http://company.com/dir/page.html</span></code> 的同源检测(假设<code>http://company.com/dir/page.html</code> 将其 <code>document.domain</code> 设置为“<code>company.com</code>”,以表明它希望允许这样做 - 更多有关信息,请参阅 {{domxref("document.domain")}} )。然而,<code>company.com</code> 不能设置 <code>document.domain</code> 为 <code>othercompany.com</code>,因为它不是 <code>company.com</code> 的父域。</p>
+
+<p>端口号是由浏览器另行检查的。任何对document.domain的赋值操作,包括 <code>document.domain = document.domain</code> 都会导致端口号被重写为 <code>null</code> 。因此 <code>company.com:8080</code> <strong>不能</strong>仅通过设置 <code>document.domain = "company.com"</code> 来与<code>company.com</code> 通信。必须在他们双方中都进行赋值,以确保端口号都为 <code>null</code> 。</p>
+
+<div class="note">
+<p>注意:使用 <code>document.domain</code> 来允许子域安全访问其父域时,您需要在父域和子域中设置 document.domain 为相同的值。这是必要的,即使这样做只是将父域设置回其原始值。不这样做可能会导致权限错误。</p>
+</div>
+
+<h2 id="跨源网络访问">跨源网络访问</h2>
+
+<p>同源策略控制不同源之间的交互,例如在使用{{domxref("XMLHttpRequest")}} 或 {{htmlelement("img")}} 标签时则会受到同源策略的约束。这些交互通常分为三类:</p>
+
+<ul>
+ <li>跨域<em><strong>写操作</strong>(Cross-origin writes)</em>一般是被允许的<em>。</em>例如链接(links),重定向以及表单提交。特定少数的HTTP请求需要添加 <a href="https://developer.mozilla.org/zh-CN/docs/HTTP/Access_control_CORS#Preflighted_requests" title="HTTP/Access_control_CORS#Preflighted_requests">preflight</a>。</li>
+ <li>跨域<em><strong>资源嵌入</strong>(Cross-origin embedding)</em>一般是被允许(后面会举例说明)。</li>
+ <li>跨域<em><strong>读操作</strong>(Cross-origin reads)</em>一般是不被允许的<em>,</em>但常可以通过内嵌资源来巧妙的进行读取访问。例如,你可以读取嵌入图片的高度和宽度,调用内嵌脚本的方法,或<a href="https://grepular.com/Abusing_HTTP_Status_Codes_to_Expose_Private_Information" title="https://grepular.com/Abusing_HTTP_Status_Codes_to_Expose_Private_Information">availability of an embedded resource</a>.</li>
+</ul>
+
+<p>以下是可能嵌入跨源的资源的一些示例:</p>
+
+<ul>
+ <li><code>&lt;script src="..."&gt;&lt;/script&gt;</code> 标签嵌入跨域脚本。语法错误信息只能被同源脚本中捕捉到。</li>
+ <li><code>&lt;link rel="stylesheet" href="..."&gt;</code> 标签嵌入CSS。由于CSS的<a href="http://scarybeastsecurity.blogspot.dk/2009/12/generic-cross-browser-cross-domain.html">松散的语法规则</a>,CSS的跨域需要一个设置正确的 HTTP 头部 <code>Content-Type</code> 。不同浏览器有不同的限制:<span> </span><a href="http://msdn.microsoft.com/zh-CN/library/ie/gg622939%28v=vs.85%29.aspx" title="http://msdn.microsoft.com/zh-CN/library/ie/gg622939%28v=vs.85%29.aspx">IE</a><span>, </span><a href="http://www.mozilla.org/security/announce/2010/mfsa2010-46.html" title="http://www.mozilla.org/security/announce/2010/mfsa2010-46.html">Firefox</a><span>, </span><a href="http://code.google.com/p/chromium/issues/detail?id=9877" title="http://code.google.com/p/chromium/issues/detail?id=9877">Chrome</a><span>, </span><a href="http://support.apple.com/kb/HT4070" title="http://support.apple.com/kb/HT4070">Safari</a><span> (跳至CVE-2010-0051)部分 和 </span><a href="http://www.opera.com/support/kb/view/943/" title="http://www.opera.com/support/kb/view/943/">Opera</a>。</li>
+ <li>通过 {{htmlelement("img")}} 展示的图片。支持的图片格式包括PNG,JPEG,GIF,BMP,SVG,...</li>
+ <li>通过 {{htmlelement("video")}} 和 {{htmlelement("audio")}} 播放的多媒体资源。</li>
+ <li>通过 <code><a href="https://developer.mozilla.org/zh-CN/docs/HTML/Element/object" title="HTML/Element/object">&lt;object&gt;</a></code>、 <a href="https://developer.mozilla.org/zh-CN/docs/HTML/Element/embed" title="HTML/Element/embed"><code>&lt;embed&gt;</code></a> 和 <code><a href="https://developer.mozilla.org/zh-CN/docs/HTML/Element/applet" title="HTML/Element/applet">&lt;applet&gt;</a></code> 嵌入的插件。</li>
+ <li>通过 <code><a href="https://developer.mozilla.org/zh-CN/docs/CSS/@font-face" title="CSS/@font-face">@font-face</a></code> 引入的字体。一些浏览器允许跨域字体( cross-origin fonts),一些需要同源字体(same-origin fonts)。</li>
+ <li><font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);">通过</span></font> <code><a href="https://developer.mozilla.org/zh-CN/docs/HTML/Element/iframe" title="HTML/Element/iframe">&lt;iframe&gt;</a></code> 载入的任何资源。站点可以使用 <a href="https://developer.mozilla.org/zh-CN/docs/HTTP/X-Frame-Options" title="HTTP/X-Frame-Options">X-Frame-Options</a> 消息头来阻止这种形式的跨域交互。</li>
+</ul>
+
+<h3 id="如何允许跨源访问"><strong>如何允许跨源访问</strong></h3>
+
+<p>可以使用 <a href="https://developer.mozilla.org/zh-CN/docs/HTTP/Access_control_CORS">CORS</a> 来允许跨源访问。CORS 是 {{Glossary("HTTP")}} 的一部分,它允许服务端来指定哪些主机可以从这个服务端加载资源。</p>
+
+<h3 id="如何阻止跨源访问"><strong>如何阻止跨源访问</strong></h3>
+
+<ul>
+ <li>阻止跨域写操作,只要检测请求中的一个不可推测的标记(CSRF token)即可,这个标记被称为 <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><span> 标记。你必须使用这个标记来阻止页面的跨站读操作。</span></li>
+ <li><span>阻止资源的跨站读取,需要保证该资源是不可嵌入的。阻止嵌入行为是必须的,因为嵌入资源通常向其暴露信息。</span></li>
+ <li><span>阻止跨站嵌入,需要确保你的资源不能通过以上列出的可嵌入资源格式使用。浏览器可能不会遵守 <code>Content-Type</code> 头部定义的类型。例如,如果您在HTML文档中指定 <code>&lt;script&gt;</code> 标记,则浏览器将尝试将标签内部的 HTML 解析为JavaScript。 当您的资源不是您网站的入口点时,您还可以使用CSRF令牌来防止嵌入。</span></li>
+</ul>
+
+<h2 id="跨源脚本API访问">跨源脚本API访问</h2>
+
+<p>JavaScript 的 API 中,如<span> </span><code><a href="https://developer.mozilla.org/zh-CN/docs/DOM/HTMLIFrameElement" title="DOM/HTMLIFrameElement">iframe.contentWindow</a></code>、<span> {{domxref("window.parent")}}、{{domxref("window.open")}} 和 {{domxref("window.opener")}} 允许文档间直接相互引用。当两个文档的源不同时,这些引用方式将对</span><span> </span><a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#security-window" title="http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#security-window">Window</a><span> 和 </span><a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html#security-location" title="http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html#security-location">Location</a>对象的访问添加限制,如下两节所述。</p>
+
+<p>为了能让不同源中文档进行交流,可以使用 {{domxref("window.postMessage")}}。</p>
+
+<p>规范: <a href="https://html.spec.whatwg.org/multipage/browsers.html#cross-origin-objects">HTML Living Standard § Cross-origin objects</a> 。</p>
+
+<h3 id="Window">Window</h3>
+
+<p> 允许以下对 <code>Window</code> 属性的跨源访问:</p>
+
+<table class="fullwidth-table standard-table">
+ <thead>
+ <tr>
+ <th scope="col">方法</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="fullwidth-table standard-table">
+ <thead>
+ <tr>
+ <th scope="col">属性</th>
+ <th scope="col"></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>{{domxref("window.closed")}}</td>
+ <td>只读.</td>
+ </tr>
+ <tr>
+ <td>{{domxref("window.frames")}}</td>
+ <td>只读.</td>
+ </tr>
+ <tr>
+ <td>{{domxref("window.length")}}</td>
+ <td>只读.</td>
+ </tr>
+ <tr>
+ <td>{{domxref("window.location")}}</td>
+ <td>读/写.</td>
+ </tr>
+ <tr>
+ <td>{{domxref("window.opener")}}</td>
+ <td>只读.</td>
+ </tr>
+ <tr>
+ <td>{{domxref("window.parent")}}</td>
+ <td>只读.</td>
+ </tr>
+ <tr>
+ <td>{{domxref("window.self")}}</td>
+ <td>只读.</td>
+ </tr>
+ <tr>
+ <td>{{domxref("window.top")}}</td>
+ <td>只读.</td>
+ </tr>
+ <tr>
+ <td>{{domxref("window.window")}}</td>
+ <td>只读.</td>
+ </tr>
+ </tbody>
+</table>
+
+<p>某些浏览器允许访问除上述外更多的属性。</p>
+
+<h3 id="Location">Location</h3>
+
+<p>允许以下对 <code>Location</code> 属性的跨源访问:</p>
+
+<table class="fullwidth-table standard-table">
+ <thead>
+ <tr>
+ <th scope="col">方法</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>{{domxref("location.replace")}}</td>
+ </tr>
+ </tbody>
+</table>
+
+<table class="fullwidth-table standard-table">
+ <thead>
+ <tr>
+ <th scope="col">属性</th>
+ <th scope="col"></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>{{domxref("URLUtils.href")}}</td>
+ <td>只写.</td>
+ </tr>
+ </tbody>
+</table>
+
+<p>某些浏览器允许访问除上述外更多的属性。</p>
+
+<h2 id="跨源数据存储访问">跨源数据存储访问</h2>
+
+<p>访问存储在浏览器中的数据,如 <a href="https://developer.mozilla.org/zh-CN/docs/Web/Guide/API/DOM/Storage">localStorage</a> 和 <a href="https://developer.mozilla.org/zh-CN/docs/IndexedDB">IndexedDB</a>,是以源进行分割。每个源都拥有自己单独的存储空间,一个源中的 JavaScript 脚本不能对属于其它源的数据进行读写操作。</p>
+
+<p>{{glossary("Cookie", "Cookies")}}  使用不同的源定义方式。一个页面可以为本域和其父域设置 cookie,只要是父域不是公共后缀(public suffix)即可。Firefox 和 Chrome 使用 <a href="http://publicsuffix.org/">Public Suffix List</a> 检测一个域是否是公共后缀(public suffix)。Internet Explorer 使用其内部的方法来检测域是否是公共后缀。不管使用哪个协议(HTTP/HTTPS)或端口号,浏览器都允许给定的域以及其任何子域名(sub-domains) 访问 cookie。当你设置 cookie 时,你可以使用 <code>Domain</code>、<code>Path</code>、<code>Secure</code>、和 <code>HttpOnly</code> 标记来限定其可访问性。当你读取 cookie 时,你无法知道它是在哪里被设置的。 即使您只使用安全的 https 连接,您看到的任何 cookie 都有可能是使用不安全的连接进行设置的。</p>
+
+<h2 id="参见">参见</h2>
+
+<ul>
+ <li><a href="http://www.w3.org/Security/wiki/Same_Origin_Policy" title="http://www.w3.org/Security/wiki/Same_Origin_Policy">Same-Origin Policy at W3C</a></li>
+ <li><a href="http://web.dev/secure/same-origin-policy">http://web.dev/secure/same-origin-policy</a></li>
+</ul>
+
+<div class="originaldocinfo">
+<h2 id="Original_Document_Information" name="Original_Document_Information">原始文件资料</h2>
+
+<ul>
+ <li>Author(s): Jesse Ruderman</li>
+</ul>
+</div>
+
+<div class="noinclude"></div>