csrf 同源策略不会阻止读取响应?

csrf same-origin policy doesn't prevent from reading response?

问题

我在 localhost:3000 上有以下代码 运行,在 localhost:8020 上有我的 api 运行。如果我访问 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>

解决方案

But why am I able to read the response from the first request as an attacker. Should same-origin policy not prohibit from reading the response, because I have different ports? Is it because I am allowing Origin localhost:3000 to make cross-site requests with "Access-Control-Allow-Origin: localhost:3000"?

是的,“Access-Control-Allow-Origin: localhost:3000”允许 localhost:3000 读取响应。

If Access-Control-Allow-Origin is the problem, do I have to protect my api requests with csrf-tokens or is there another way? Implementing csrf tokens is not the problem but I am wondering, if there is an different, probably smaller solution.

OWASP 建议始终使用 csrf-tokens。所以我实现了csrf-tokens。

But why am I able to read the response from the first request as an attacker. Should same-origin policy not prohibit from reading the response, because I have different ports?

默认是。

Is it because I am allowing Origin localhost:3000 to make cross-site requests with "Access-Control-Allow-Origin: localhost:3000"?

是的。明确授予 localhost:3000 读取数据的权限让 localhost:3000 读取数据。

If Access-Control-Allow-Origin is the problem, do I have to protect my api requests with csrf-tokens or is there another way?

您使用什么方法来保护端点免受攻击者的攻击很大程度上取决于:

  • 你想让谁停止做坏事
  • 您想允许这些人做什么
  • 您想允许其他人做什么