跨域安全问题学习
postMessage
postMessage
常用于当前页面与iframe内页面,传递跨域信息
如果对发送端或接受端未做校检,就会存在这样那样的问题
发送端未指定target
下面为页面aaa接受来自窗口bbb的信息
1 | <!-- http://www.aaa.com:1234/receive.html --> |
1 | <!-- http://www.bbb.com:1234/send.html --> |
正常状态如下:
但是上面发送端代码中指定target为*
,意味着任意域都可以接收这一信息
在恶意网站ccc上布置接收代码,用户访问后,就可以拿到用户的SercretKey
接收端未校检origin
下面为aaa向窗口bbb传递信息SecretKey,bbb接收到后将内容显示到页面里
1 | <!-- http://www.aaa.com:1234/send.html --> |
1 | <!-- http://www.bbb.com:1234/receive.html --> |
正常状态如下:
但是在bbb中的接收代码中,没有对发送信息的来源进行校检
我们可以搭建一个恶意网站,伪造信息发送过去
1 | <!-- http://www.evil.com:8888/evil.html --> |
上面的代码其实就是正常往目标传递信息,但是发送内容变成了XSS代码,用户访问我们的恶意界面后
防御方案
发送端指定target
1 | <script> |
接收端对origin进行校检
1 | <p id="text"></p> |
JSONP劫持
jsonp不像postMessage那样需要用iframe来进行跨域数据传输,而是活用script标签进行跨域数据请求
1 | # http://www.bbb.com:1234/test.php |
1 | <!-- http://www.aaa.com:1234/index.html --> |
index.html中,第一个script标签先声明了一个函数jsonp(message)
,后面的script标签跨域获取数据作为js代码执行,等于执行了函数jsonp({"id":1, "name":"x1a0t"})
,于是我们将另一个站的数据成功引进入到了当前站的网页中
但是可以看到test.php代码中并没有对请求者进行校检,攻击人员可以构造恶意界面让用户访问,即可窃取用户敏感信息
防御方案
jsonp劫持属于CSRF范畴,可添加token校检代码
以及test.php中的代码需要做好XSS防御,即限制返回包Content-type不要为html
CORS
jsonp是通过script标签GET请求获取的信息,如果需要用到POST等方法请求数据,就需要用CORS(跨域资源请求)
我们的请求包中如果有Origin头,就会被判定为CORS请求,服务端会在返回包中以Access为前缀的头就会起作用,关键的有两个
- Access-Control-Allow-Origin,必须,允许的Origin
- Access-Control-Allow-Credentials,可选,允许发送cookies等凭证
举例,某线上业务中,前端页面aaa通过某个后端api(bbb),根据用户cookie等凭证取出用户信息,返回到当前页面中
1 | <!-- http://www.aaa.com:1234/index.html --> |
1 |
|
用户有bbb需要的凭证,然后访问aaa页面,aaa发起CORS请求,bbb验证凭证后取出信息返回,浏览器判断返回包是否允许当前域,是否允许凭证,都允许则取出数据,正常情况如下
如果CORS出现错误配置Access-Control-Allow-Origin: *
,即允许所有的Origin,就会造成CORS攻击
攻击者可以构建恶意网页让用户访问,窃取用户敏感信息
防御方案
通过Access-Control-Allow-Origin
指定允许特定的origin
CSWH
WebSocket拥有支持双向通信,实时性较强,还支持二进制通信等优点
如果WebSocket服务器没有限制Origin,任何站点均可向服务器发起连接,就存在CSWH(跨站Websocket劫持)
如果服务器没有限制Access-Control-Allow-Origin
,那么任何域均可能取得服务器返回的信息,类似于CORS
Reference
https://www.freebuf.com/vuls/194714.html
http://sh1yan.top/2018/08/12/jsonp-study
https://www.jianshu.com/p/3a9ed30233f6
https://zhuanlan.zhihu.com/p/61044032