0x00 概述
同源策略(SOP)是浏览器的一个安全策略,它的存在限制了非同源网站之间脚本和资源的交互。举个例子,如果没有同源策略,A 网站可以获取到属于 B 网站的所有资源。包括用户在 B 网站上的 cookie 等敏感信息都可以被 A 网站获取到。
0x01 源的定义
源就是指资源的作用域,包括三点 —— 协议、域名、端口。只要这三点都相同的,就是同源。
具体的例子可以看下图
0x02 实验:用 XHR 测试浏览器对非同源请求响应
使用 Firefox 中访问百度(https://www.baidu.com),然后 F12 打开 console,new 一个 XHR 对象
var request = new XMLHttpRequest();
然后我们用这个对象分别来测试请求在协议、域名、端口不同的情况下浏览器的响应。
不同协议
先测试不同协议ftp
和https
request.open("get", "ftp://www.baidu.com")
request.send();
警告
已拦截跨源请求:同源策略禁止读取位于 ftp://www.baidu.com/ 的远程资源。(原因:CORS 请求不是 http)。
警告告诉我们这是个跨源请求(已经证明协议不同非同源了,实验的目的已经达到了)。至于警告后面的部分,其实是因为 CORS 请求只能用 HTTP ,而我们用了 ftp~
另外我为什么不用”http://www.baidu.com”来测试,那是因为新版本的 Firefox 会将 XHR 从 HTTPS 发送到 HTTP 的请求作为”混合活动内容“,并阻止载入。
不同域名
测试不同域名www.baidu.com
和baidu,com
request.open("GET", "https://baidu.com");
request.send();
警告
已拦截跨源请求:同源策略禁止读取位于 https://baidu.com/ 的远程资源。(原因:CORS 头缺少 ‘Access-Control-Allow-Origin’)。 已拦截跨源请求:同源策略禁止读取位于 https://baidu.com/ 的远程资源。(原因:CORS 请求未能成功)。
也是跨源请求,后面警告是因为 Request 里没带上 Access-Control-Allow-Origin 头~
另外,我们一直开着的 burp 也抓到了我们发出去的包,并收到了返回包,这说明同源策略拦截的是响应,而不是请求
P.S. 测试不同协议的时候没抓到包是因为 burp 本来就抓不到 ftp 的包~
不同端口
测试不同端口443
和9000
request.open("GET", "https://www.baidu.com:9000");
request.send();
警告
已拦截跨源请求:同源策略禁止读取位于 https://www.baidu.com:9000/ 的远程资源。(原因:CORS 头缺少 ‘Access-Control-Allow-Origin’)。
也是跨源请求,被拦截了
同源
最后再来个同源请求来对照
request.open("GET", "https://www.baidu.com");
request.send();
没有任何警告,因为只是同源下的请求。
0x03 跨域以及跨域所导致的安全问题
有了同源策略,网站的安全性的确提高了,但是可用性降低了。为了在安全性和可用性中取得平衡,SOP 提供了一些方法来实现资源的跨域,不过这降低了部分安全性,导致出现了一些安全问题。
跨域与跨站攻击(XSS、CSRF)
比如 A 站点想要 B 站点上面的一张图片来做背景,但是由于 A、B两个站点的域名不同(可能连协议端口都不同)所有由于同源策略的限制,A 站点无法获取这张图片。但事实上我们都知道只要一个<img>
标签就能获取到图片,这就证明<img>
标签并没有像我们想象中一样执行 SOP,同样<video>
、<audio>
、<iframe>
等标签也有类似的情况。
其实在 SOP 中规定了带有herf
、src
属性的标签可以跨域“嵌入”资源(Cross-origin embedding),但不能读取。
XSS 正是靠这些标签来使攻击者在自己服务器上构造的 XSS Payload 嵌入到目标网站上的。而 POST CSRF 也是同样使用了这些标签实现跨站(Cross Site)的。
在完全符合 SOP 的规范的情况下,攻击者可以通过这两种跨站攻击让受害者客户端执行操作(XSS 执行 JS / CSRF 发送请求)。
JSONP 的安全问题
打算单独写一篇文章,待更新
CORS 的安全问题
同上
2019.10.10 更新:写的草稿在电脑重置后遗失了,果然把未归档的文件留在 C 盘不是好习惯。正好找到一篇 dalao 的文章,在此推荐《 cors安全部署最佳实践 》
0x04 Cookie 的源
Cookie 的“源”并不遵守同源策略中“源”的定义,而是仅由域名和路径限制。实现方法就是 Cookie 中加上 Domain 和 Path 标识,之前在相关文章里面写过,故不再赘述。
具体可以看这篇文章 - 《 HTTP 会话机制 》 “Cookie 安全”一节中的“Domain 和 Path 标记”部分
0x05 参考
- 浏览器的同源策略 - MDN
- 浏览器同源政策及其规避方法 - 阮一峰
- 对于浏览器的同源策略你是怎样理解的呢? - 王泥煤