【问题标题】:csrf same-origin policy doesn't prevent from reading response?csrf 同源策略不会阻止读取响应?
【发布时间】: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


【解决方案1】:

但是为什么我能够作为攻击者读取第一个请求的响应。同源策略不应该禁止读取响应,因为我有不同的端口吗?

默认情况下是的。

是因为我允许 Origin localhost:3000 使用“Access-Control-Allow-Origin: localhost:3000”进行跨站请求吗?

是的。显式授予 localhost:3000 读取数据的权限让 localhost:3000 读取数据。

如果 Access-Control-Allow-Origin 是问题所在,我必须使用 csrf-tokens 保护我的 api 请求还是有其他方法?

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

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

【讨论】:

  • 如果我必须允许多个网站向我的 API 发出请求。然后我必须允许所有来源,接下来,攻击者可以看到响应。因此,除了使用 csrf-tokens 检查来源之外,没有其他方法可以保护我的 API 免受 csrf 攻击。你能确认一下吗?
  • "那么我必须允许所有来源" — 不,只有您想要允许访问的来源。
  • OWASP 建议检查原始标头作为二级保护并始终实施 csrf 令牌。我想我也会使用 csrf-tokens 并检查源头。
猜你喜欢
  • 2017-05-02
  • 2017-05-09
  • 2021-04-04
  • 2014-10-17
  • 2015-07-22
  • 1970-01-01
相关资源
最近更新 更多