CORS测试

什么是CORS

CORS指Cross-Origin Resource Sharing,浏览器用来判断是否可以访问其他网站的资源和服务,比如AJAX跨域。

比如说A站点的页面需要通过AJAX请求B站点的服务,浏览器发送AJAX请求时会增加Origin头:

1
Origin: http://foo.bar

之后B站点收到请求,分析Origin,如果允许就返回相应的Access-Control-Allow-Origin字段:

1
Access-Control-Allow-Origin: http://foo.bar

Access-Control-Allow-Origin用来指定允许哪些域名CORS,浏览器根据这个值来决定请求要不要正常给A站点。这一字段有可能配置不当引起任意跨域。

如何测试

给目标站点发送一个包含Origin的request:

1
2
3
4
5
6
7
8
9
GET http://target.domain/file.php HTTP/1.1
Host: target.domain
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8;)
Gecko/20100101 Firefox/24.0
Accept: text/html
Accept-Language: en-US
Referer: http://foo.bar/
Origin: http://foo.bar/
Connection: keep-alive

如果返回Response包含Access-Control-Allow-Origin: *,表示允许任何网站跨域请求:

1
2
3
4
5
6
7
8
9
10
HTTP/1.1 200 OK
Date: Fri, 23 NOV 2018 18:57:53 GMT
Server: Apache/2.2.22 (Debian)
X-Powered-By: PHP/5.4.4-14+deb7u3
Access-Control-Allow-Origin: *
Content-Length: 44
Keep-Alive: timeout=18, max=89
Connection: Keep-Alive
Content-Type: application/xml
[Response Body]

还有另一种情况,如果你发送一个随意的Origin值,对方会返回相同的Access-Control-Allow-Origin 值。
测试工具的话,随意找个发送header头的就能测试,比如burpsuite、curl。
另外我写了个脚本来判断 https://github.com/coldhurt/pycode/blob/master/cors_check.py
因为Origin可以更改,所以不推荐根据Origin来生成Access-Control-Allow-Origin值,正确做法是用固定的值,只允许那些你允许的网站。

参考:https://www.owasp.org/index.php/CORS_OriginHeaderScrutiny