+ 前端

浏览器的同源策略
2024-04-16

目录:

同源策略是浏览器中的一个安全策略,限制两个不同网站之间文档和脚本资源的相互影响,保护用户数据不会泄露到另一个的网站中。有关这个概念的解释很多,但是都不是很清晰,关于这个安全策略具体细节,我想是时候整理一下了。

什么是同源策略

同源策略(Same Origin Policy, SOP),由 Netscape 公司 1995 年引入浏览器,是浏览器最基本的安全策略。如果缺少了同源策略,浏览器很容易受到 XSS、CSFR 等攻击。

源(Origin)是指 协议(Protocol) 主机(Host) 端口(Port) 组成的部分。

源(Origin)

同源(Same Origin)即要求组成源的三个部分都相同。如果非同源,发起请求时就会返回跨域错误。

源(Origin)

非同源限制

  • 非同源请求被拦截
  • 非同源文档(DOM) JavaScript 不可读写
  • 非同源数据 JavaScript 不可读写
    • Cookie 不可读写,但子域可以为父域写 Cookie
    • Web Storage 和 IndexedDB 不可读写
  • 允许 GET 和 POST 发起跨域请求,但拒绝 PUT 和 DELETE 发起跨域请求。
  • 请求不能使用自定义标头,例如 X-Custom-Header

非同源对象的访问

浏览器中,JavaScript 可以获取其他窗口的 Window 对象,但在非同源的界面中,会限制只允许交互其他网页的 Window 对象的四个方法和九个属性。

方法 说明
window.blur() 用于将焦点从指定的窗口移开
window.close() 用于关闭当前的浏览器窗口
window.focus() 用于将用户的焦点设置到指定的窗口
window.postMessage() 允许在不同的窗口或者 iframe 之间进行数据传递
属性 状态 描述
window.closed 只读 返回一个布尔值,表示窗口是否已经关闭。
window.frames 只读 返回当前窗口,一个类数组对象,列出了当前窗口的所有直接子窗口
window.length 只读 返回当前窗口中包含的框架数量 (框架包括 frame 和 iframe 两种元素)
window.location 读/写 返回一个 Location 对象,其中包含有关文档当前位置的信息
window.opener 只读 返回打开当前窗口的那个窗口的引用
window.parent 只读 返回当前窗口的父窗口对象。如果一个窗口没有父窗口,则它的 parent 属性为自身的引用。如果当前窗口是一个 <iframe>, <object>, 或者 <frame>,则它的父窗口是嵌入它的那个窗口
window.self 只读 返回一个指向当前 window 对象的引用
window.top 只读 返回窗口层级最顶层窗口的引用
window.window 只读 返回对 window 自身的引用

同样的,Location 对象也会在非同源页面中被限制只允许交互其他网页的 Location 对象的一个方法和一个属性

方法 说明
location.replace() 给定的 URL 来替换当前的资源
属性 状态 描述
HTMLAnchorElement.href 只写 一个返回包含整个 URL 的字符串的 stringifier,且允许 href 被更新

同源策略白名单

在浏览器中,默认允许部分标签通过 GET 请求获取跨源数据:

标签 属性 说明
<script> src 标签嵌入的 JavaScript 脚本
<link> href 标签嵌入的 CSS。由于 CSS 的松散的语法规则,CSS 的跨源必须设置正确的 Content-Type 标头。如果样式表是跨源的,且 MIME 类型不正确,资源不以有效的 CSS 结构开始,浏览器会阻止它的加载
<img> src 用于展示的图片
<video> src 播放的视频资源
<audio> src 播放的音频资源
<object> data 嵌入的外部资源或插件
<embed> src 嵌入的外部内容
<iframe> src 载入的任何资源。站点可以使用 X-Frame-Options 标头来阻止这种形式的跨源交互

结语

浏览器保留的部分对象和标签对非同源资源的访问,这促成了早期浏览器解决同源策略限制方案的诞生。考虑到跨域技术的多样性,我觉得有必要后续花时间整理一下。

本文作者: Exisi 本文链接: 版权声明:本博客所有文章除特别声明外,均默认采用 CC BY-NC-SA 4.0 许可协议。