Ashing's Blog

想学的太多 懂得的太少

0%

WEB安全—SOP策略

0x01 浏览器的同源策略(What?)

1 同源策略(Same-Origin Policy)

同源策略是 Netscape 公司引入的安全策略,目前所有浏览器都会实行 SOP 策略,是浏览器最核心、最基本的安全功能

最初,它的含义是指,A 网页设置的 Cookie,B 网页不能打开,除非这两个网页 “同源” 。所谓 “同源” 指的是 “三个相同” 。

同源策略仅存在于浏览器客户端,不存在 Android、iOS、NodeJS、Python、Java 等其他环境。

flash、java applet、silverlight、googlegears 等浏览器加载的第三方插件也有各自的同源策略,只是这些同源策略不属于浏览器原生的同源策略,如果有漏洞则可能被黑客利用,从而留下 XSS 攻击的后患

2 同源的定义

如果两个页面的协议、端口(如果有指定)和主机都相同,则两个页面具有相同的源。可以称为:tuple

1
2
tuple:协议、域名、端口  # 或者简单地叫做"tuple",即元
“元”,是指一些事物组合在一起形成一个整体,比如(12)叫二元,(123)叫三元
url 结果 原因
http://abc.jjp.com/app/page2.html 同源 只有路径不同
http://abc.jjp.com/source/page2.html 同源 只有路径不同
https://abc.jjp.com/app/dist/page3.html 不同源 协议不相同
http://efg.jjp.com/app/page2.html 不同源 域名不相同
http://abc.jjp.com:8080/app/page2.html 不同源 端口不相同

IE例外:IE 非标准的策略

  1. 范围:两个相互之间高度互信的域名,如公司域名,不遵守同源策略的限制
  2. 端口:IE 未将端口号加入到同源策略的组成部分之中,即同域名不同端口属于同源

3 源的继承

被创建的窗口从创建它的脚本那里继承对应的源,如:弹窗?

4 源的更改

同源策略认为域和子域属于不同的域,例如: child1.a.coma.com

对于这种情况,可以在两个方面各自设置 document.domain='a.com' 来改变其源来实现以上任意两个页面之间的通信。

22 年更新:目前已被弃用,虽然一些浏览器可能仍然支持,但从标准中删除。因为它破坏了同源策略所提供的安全保护,并使浏览器中的源模型复杂化,导致互操作性问题和安全漏洞。

5 同源策略限制的范围

  • Cookie、LocalStorage 和 IndexDB 无法读取,localStorage、IndexedDB等数据存储会以源进行分割,每个源拥有自己独立的存储空间,一个源的 js 脚本不能对属于其他源的数据进行读写操作

  • DOM 无法获得(Document Object Model 译为文档对象模型,是HTML 和 XML 文档的编程接口)

  • Ajax 请求不能发送

0x02 同源策略的目的(Why?)

  • 防止敏感信息泄露:A 网站是一家银行,用户登录以后,又去浏览其他网站。如果其他网站可以读取 A 网站的 Cookie,那么就会泄露用户的隐私信息(比如:存款总额)
  • 防止非授权访问:Cookie 往往保存用户的登录状态,如果用户没有退出登录,且黑客盗取了用户的 Cookie 则可以冒充用户进行任何操作(浏览器规定,提交表单不受同源政策的限制)

0x03 实现跨域读取的方案(How?)

为什么要实现跨域请求?

工程服务化后,不同职责的服务分散在不同的工程中,往往这些工程的域名是不同的,但一个需求可能对应到多个服务,这时便需要调用不同服务的接口,因此会出现跨域。

注意:跨域请求能成功发送,服务端能接收请求并正常返回结果,只是结果被浏览器拦截了。

跨源网络访问

跨域写:通常允许。比如:链接、重定向和表单提交(因为表单提交不需要反馈数据)

跨域资源嵌入:通常允许。避免跨域资源嵌入:需要确保html文档中没有允许跨域资源嵌入的标签

跨域读:通常不允许。比如:在使用 XMLHttpRequest 的时候会发生跨域问题,不过通过某些方法仍可以进行跨域读

1 代理

浏览器请求同源服务器,再由后者请求外部服务

2 JSONP

简单适用,老式浏览器全部支持。思想:网页通过添加一个<script>元素,向服务器请求 JSON 数据,请求的查询字符串有一个callback参数,用来指定回调函数的名字;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。

安全问题:JSONP 劫持

3 WebSocket

WebSocket是一种通信协议,使用ws://(非加密)和wss://(加密)作为协议前缀。该协议不实行同源政策,只要服务器支持,就可以通过它进行跨源通信。

4 CORS

CORS是跨源资源分享(Cross-Origin Resource Sharing)是W3C标准,是跨源 AJAX 请求的根本解决方法。相比 JSONP 只能发GET请求,CORS允许任何类型的请求。

CORS请求大致和Ajax请求类似,但是在HTTP头信息中加上了Origin字段表明请求来自哪个源。

5 跨窗口的跨域通信

  • 片段识别符

  • window.name

  • window.postMessage:跨文档通信API(Cross-document messaging)

0x04 阻止跨域读取

避免跨域写:在发起写请求中携带一个隐藏的token,然后服务器端对这个token进行验证,多用来防范CSRF攻击

避免跨域读:要保证返回给客户端的资源是不可嵌入的,不可以是上面列出的允许跨域资源嵌入的标签

0x05 Cookie的跨域访问控制

  • cookies 同样只有同源网页才能共享,设置其 domain、path、secure、HttpOnly 属性可以来限定其访问性
属性 作用
domain 指定cookies对哪个域有效,cookies 只会发向该域,默认值是设置 cookie 的那个域
path 表示相对于 domain 的路径,只有在该路径下才能拿到cookies,默认值为 /
secure 设置了该属性或者设置了 ‘secure=true’ 表示只能在 HTTPS 连接中传递 cookies
HttpOnly 设置了该属性或这设置了 ‘HttpOnly=true’ 表示 js 脚本不能读取到cookie信息

Reference

1
2
3
4
https://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html
https://www.ruanyifeng.com/blog/2016/04/cors.html
https://tsejx.github.io/javascript-guidebook/computer-networks/web-security/same-origin-policy/
https://wiki.wgpsec.org/knowledge/web/same-origin-policy.html