同源策略

Mariko Kosaka

同源策略是一种浏览器安全功能,它限制一个源的文档和脚本如何与另一个源的资源进行交互。

浏览器可以同时加载和显示来自多个站点的资源。您可能同时打开了多个标签页,或者一个站点可能嵌入了来自不同站点的多个 iframe。如果对这些资源之间的交互没有限制,并且脚本被攻击者入侵,则该脚本可能会暴露用户浏览器中的所有内容。

同源策略通过阻止对从不同源加载的资源的读取访问来防止这种情况发生。“但是等等,”您会说,“我一直从其他源加载图像和脚本。” 浏览器允许一些标签嵌入来自不同源的资源。此策略主要是一个历史遗留问题,可能会使您的站点容易受到诸如 使用 iframe 进行点击劫持之类的漏洞攻击。您可以使用 内容安全策略来限制对这些标签的跨源读取。

什么是同源?

源由方案(也称为协议,例如 HTTP 或 HTTPS)、端口(如果已指定)和主机定义。当两个 URL 的这三者都相同时,它们被视为同源。例如,http://www.example.com/foohttp://www.example.com/bar 是同源的,但与 https://www.example.com/bar 不是同源的,因为方案不同。

哪些是允许的,哪些是被阻止的?

通常,嵌入跨源资源是允许的,而读取跨源资源是被阻止的。

iframes 通常允许跨源嵌入(取决于 X-Frame-Options 指令),但不允许跨源读取(例如使用 JavaScript 访问 iframe 中的文档)。
CSS 可以使用 <link> 元素或 CSS 文件中的 @import 嵌入跨源 CSS。可能需要正确的 Content-Type 标头。
表单 跨源 URL 可以用作表单元素的 action 属性值。Web 应用程序可以将表单数据写入跨源目标。
图片 允许嵌入跨源图片。但是,阻止读取跨源图片数据(例如使用 JavaScript 从跨源图片检索二进制数据)。
多媒体 可以使用 <video><audio> 元素嵌入跨源视频和音频。
脚本 可以嵌入跨源脚本;但是,可能阻止访问某些 API(例如跨源 fetch 请求)。

TODO: DevSite - 思考和检查评估

如何防止点击劫持

clickjacking
图:点击劫持机制在 3 个单独的层(基础站点、iframe 站点、透明按钮)中进行说明。

一种名为“点击劫持”的攻击将站点嵌入到 iframe 中,并覆盖透明按钮,这些按钮链接到不同的目标。用户被欺骗,以为他们正在访问您的应用程序,同时将数据发送给攻击者。

要阻止其他站点将您的站点嵌入到 iframe 中,请将具有 frame-ancestors 指令的内容安全策略添加到 HTTP 标头。

或者,您可以将 X-Frame-Options 添加到 HTTP 标头,请参阅 MDN 以获取选项列表。

总结

希望您会因为浏览器努力成为 Web 安全的守门人而感到稍微放心。即使浏览器试图通过阻止访问资源来确保安全,但有时您仍希望在应用程序中访问跨源资源。在下一指南中,了解跨源资源共享 (CORS) 以及如何告诉浏览器允许从受信任源加载跨源资源。