同源策略总结
同源策略是浏览器相当重要的安全功能,不同源在没有明确授权的情况下,不能读写其他源的资源。
源是什么?
同源策略的源
(origin)就是协议
、域名
和端口号
。
例如:
1
https://www.tr0y.wang:80/2019/06/02/同源策略详解
这个 url 的源是 https://www.tr0y.wang:80
,若地址里面的协议(https
)、域名(www.tr0y.wang
)和端口号(80
)均相同则属于同源
如何判断是否同源?
同源检测举例:
https://www.tr0y.wang
:同源https://tr0y.wang:80/2019/06/02/同源策略详解
:不同源,因为域名不同http://www.tr0y.wang:80/2019/06/02/同源策略详解
:不同源,因为协议不同https://www.tr0y.wang:8080/2019/06/02/同源策略详解
:不同源,因为端口不同
同源策略限制了什么?
在讲清楚这个问题之前,我想起了之前的一个有趣经历。
大概在 2016 年?我的一个高中同学的 qq 被盗了,盗号的在各个好友之间试图骗我们充话费。这种一般都是脚本小子,我就想定他的位吓唬一下他,于是我在服务器上开了个 80,利用短网址服务将 ip 转为短链之后,发给他骗他点开,大意是“我帮你充好了,你点击去确认一下”。他还真的点了,顺利拿到了 ip,经过查找定位是上海的,然后一顿威胁报警,还真怂了,告诉我新密码,就退 qq 了。。。其实 ip 地址不一定能精确定位,这个脚本小子的胆子太小了。
这件事过后,我突发奇想,为何不在自己的网页中用 iframe 嵌入 qq 相关的页面(比如 qq 空间),如果点击的人登录了 qq 空间,我便能利用精心构造的 js 拿到点击我网页的人的 qq 号了(手机号等等信息同理),威胁等级直线上升;或者直接嵌入一个百度地图,省去拿到 ip 再定位的过程。于是在当天我立马写了一个 demo 出来。
但是经过尝试,虽然 qq 空间的 iframe 加载成功了,但是我页面中的 js 始终没法拿到 qq 空间的 iframe 中的数据,这让我百思不得其解。经过 google 才知道是浏览器同源策略的限制,虽然之前一直知道有这么个东西,但是完全不知道起着什么作用,经过那天的事才深刻理解。
通过以上的故事可以清楚地看到,我试图嵌入 iframe 的想法很像 CSRF 攻击的雏形,而获取 iframe 中的元素就是同源策略要限制的东西(仅仅是其中的一部分)。
所以同源策略到底限制了哪些行为呢?
- 无法读取 Cookie、LocalStorage 和 IndexedDB
- 无法获得 DOM(如嵌入的iframe)
- 不能发送 AJAX 请求(注意,之前的浏览器是不能发送的,但是后来放松了限制,AJAX 能发服务器也能收得到,但是浏览器默认阻止 js 获取响应的内容。个人感觉是 CORS 出了之后改的)
最后 <script>
、<img>
、<link>
、<frame>
等标签都可加载跨域资源,而不受同源策略限制,带src
属性的标签加载时,实际上是由浏览器发起一次 GET 请求,不同于 XMLHttpRequest
。
必须要跨域通信怎么办?
阮一峰讲的很好了,详见:传送门🚪
来呀快活呀