浏览器的同源策略
同源策略是浏览器中的一个安全策略,限制两个不同网站之间文档和脚本资源的相互影响,保护用户数据不会泄露到另一个的网站中。有关这个概念的解释很多,但是都不是很清晰,关于这个安全策略具体细节,我想是时候整理一下了。
什么是同源策略
同源策略(Same Origin Policy, SOP),由 Netscape 公司 1995 年引入浏览器,是浏览器最基本的安全策略。如果缺少了同源策略,浏览器很容易受到 XSS、CSFR 等攻击。
源(Origin)是指 协议(Protocol)
主机(Host)
端口(Port)
组成的部分。
同源(Same Origin)即要求组成源的三个部分都相同。如果非同源,发起请求时就会返回跨域错误。
非同源限制
根据实际的开发逻辑,此限制大概可以分为两类,即请求限制和 JavaScript 限制。
请求限制
- 非同源请求被拦截
- 允许 GET 和 POST 发起跨域请求,但拒绝 PUT 和 DELETE 发起跨域请求。
- 请求不能使用自定义标头,例如 X-Custom-Header
JavaScript 限制
- 限制读取非同源文档(DOM)
- 限制读写非同源存储数据
- Cookie 不可读写,但子域可以为父域写 Cookie
- Web Storage 和 IndexedDB 不可读写
非同源对象的访问
在浏览器中,JavaScript 通过 Window 对象提供了一系列方法和属性来与浏览器窗口进行交互。当涉及到非同源的窗口交互时,出于安全考虑,浏览器实施了一定的限制。
Window 对象
对于 Window 对象限制只允许交互以下四个方法
方法 | 说明 |
---|---|
window.blur() | 用于将焦点从指定的窗口移开 |
window.close() | 用于关闭当前的浏览器窗口 |
window.focus() | 用于将用户的焦点设置到指定的窗口 |
window.postMessage() | 允许在不同的窗口或者 iframe 之间进行数据传递 |
同时,限制只允许交互其他网页的 Window 对象的九个属性
属性 | 状态 | 描述 |
---|---|---|
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 对象的一个方法
方法 | 说明 |
---|---|
location.replace() | 给定的 URL 来替换当前的资源 |
同时,限制只允许交互其他网页的 Location 对象的一个属性
属性 | 状态 | 描述 |
---|---|---|
location.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 标头来阻止这种形式的跨源交互 |
结语
浏览器保留的部分对象和标签对非同源资源的访问,这促成了早期浏览器解决同源策略限制方案的诞生。考虑到跨域技术的多样性,我觉得有必要后续花时间整理一下。
浏览器的同源策略
http://blog.itea.dev/2024/04/16/浏览器的同源策略/