【发布时间】:2021-02-22 05:16:43
【问题描述】:
问题
我在 localhost:3000 上运行以下代码,我的 api 在 localhost:8020 上运行。如果我访问 localhost:3000,则会向 localhost:8020/user/refresh 发出请求,以获取带有 cookie 中刷新令牌的新访问令牌,并使用新的访问令牌进行响应。我现在可以使用获取的访问令牌向 localhost:8020/user/delete 发出另一个请求。
但是为什么我能够作为攻击者读取第一个请求的响应。同源策略是否应该不禁止阅读响应,因为我有不同的端口?是不是因为我允许 Origin localhost:3000 使用“Access-Control-Allow-Origin: localhost:3000”进行跨站请求?
如果 Access-Control-Allow-Origin 是问题所在,我是否必须使用 csrf-tokens 保护我的 api 请求,还是有其他方法?实现 csrf 令牌不是问题,但我想知道是否有不同的、可能更小的解决方案。
<script>
function post() {
var x = new XMLHttpRequest();
x.open("GET", "http://localhost:8020/user/refresh", true);
x.withCredentials = true;
x.setRequestHeader("Content-Type", "application/json");
x.onreadystatechange = function () {
if (x.readyState == XMLHttpRequest.DONE) {
var data = JSON.parse(x.responseText);
var x2 = new XMLHttpRequest();
x2.open("POST", "http://localhost:8020/user/delete", true);
x2.setRequestHeader("Content-Type", "application/json");
x2.setRequestHeader("Authorization", `Bearer ${data["data"]["accessToken"]}`);
x2.onreadystatechange = function () {
if (x2.readyState == XMLHttpRequest.DONE) {
console.log(x2.responseText);
}
}
x2.send(JSON.stringify({user : { "id": "2" }}));
}
}
x.send(null);
}
</script>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body onload="post()">
</body>
</html>
解决方案
但是为什么我能够作为攻击者读取第一个请求的响应。同源策略是否应该不禁止阅读响应,因为我有不同的端口?是不是因为我允许 Origin localhost:3000 使用“Access-Control-Allow-Origin: localhost:3000”进行跨站请求?
是的,“Access-Control-Allow-Origin: localhost:3000”允许 localhost:3000 读取响应。
如果 Access-Control-Allow-Origin 是问题所在,我是否必须使用 csrf-tokens 保护我的 api 请求,还是有其他方法?实现 csrf 令牌不是问题,但我想知道是否有不同的、可能更小的解决方案。
OWASP 建议始终使用 csrf-tokens。所以我实现了 csrf-tokens。
【问题讨论】:
-
我希望您也在服务器上进行真正的授权。 CSRF 令牌并不意味着授权任何操作,它仅用于检查请求是否来自源自您自己域的源。
-
@Teemu 我设置了 JWT 访问和刷新令牌。听起来我必须使用 csrf-tokens 来检查来源。
标签: javascript xmlhttprequest csrf