当前位置: 首页 > 知识库问答 >
问题:

为什么同源策略不足以防止CSRF攻击?

蓬琦
2023-03-14

首先,我假设一个后端来控制输入以防止XSS漏洞。

在这个回答中@Les Hazlewood解释了如何在客户端保护JWT。

假设所有通信都使用100%TLS,无论是在登录期间还是登录后的所有时间,通过基本身份验证使用用户名/密码进行身份验证并接收JWT作为交换是一个有效的用例。这几乎就是OAuth 2的一个流(“密码授权”)的工作原理。[...]

您只需设置授权头:

Authorization: Bearer <JWT value here>

但是,也就是说,如果您的REST客户端是“不可信的”(例如,支持JavaScript的浏览器),我甚至不会这样做:HTTP响应中可通过JavaScript访问的任何值——基本上是任何头值或响应体值——都可能通过MITM XSS攻击被嗅探和拦截。

最好将JWT值存储在仅安全、仅http的cookie中(cookie config: setSecure(true),setHttpOnly(true))。这保证了浏览器将:

  1. 只通过TLS连接传输cookie,
  2. 永远不要使cookie值对JavaScript代码可用。

这种方法几乎是实现最佳实践安全性所需的一切。最后一件事是确保您对每个HTTP请求都有CSRF保护,以确保向您的站点发起请求的外部域无法运行。

最简单的方法是设置一个具有随机值的仅安全(但不是仅http)cookie,例如UUID。

我不明白为什么我们需要带有随机值的cookie来确保向您的站点发起请求的外部域无法运行。同源策略不免费提供吗?

来自OWASP:

检查原始标头

Origin HTTP Header标准是作为防御CSRF和其他跨域html" target="_blank">攻击的方法而引入的。与引用不同,源将出现在源自 HTTPS URL 的 HTTP 请求中。

如果存在源标头,则应检查其一致性。

我知道OWASP本身的一般建议是同步器令牌模式,但我看不到仍然存在哪些漏洞:

  • TLS JWT in secure httpOnly cookie 同源策略 没有 XSS 漏洞。

更新1:同源策略只适用于XMLHTTPRequest,所以一个邪恶的网站可以很容易地发出表单POST请求,这会破坏我的安全。需要显式的源标头检查。等式是:

  • 安全httpOnly cookie源头中的TLS JWT检查无XSS漏洞

共有3个答案

冯良才
2023-03-14

我只想总结一下答案。

  1. 如前所述,SOP仅适用于XmlHttp请求。这意味着根据规范,浏览器必须发送ORIGIN标头以及通过XmlHttp请求发出的请求。
  2. 如果您选中Chromium在提交表单时也会发送原始。然而,这并不意味着其他浏览器会这样做。下图说明了在Firefox中发出的两个帖子请求。一个是通过提交表单发出的,另一个是使用XHR发出的。这两个请求都是从超文本传输协议发出的://hack: 3002/那他密码超文本传输协议://bank: 3001/chane密码
  3. 如果请求来自同一域,则允许浏览器不发送原始标头。因此,服务器应仅在设置原始标头时检查原始策略。

结论是:如果你使用cookies,一个没有< code>origin头的请求到达服务器,你不能区分它是通过从另一个域提交一个表单还是由同一个域内的XHR发出的。这就是为什么你需要额外检查CSRF。

齐泰
2023-03-14

为什么同源策略不足以防止CSRF攻击?

因为同源策略仅适用于读取数据而不写入数据。

您想避免http://compromised.com发出这样的请求(来自用户的浏览器):

POST https://example.com/transfer-funds
fromAccountId:1
toAccountId:666

合法的请求应该是这样的:

POST https://example.com/transfer-funds
fromAccountId: 1
toAccountId: 666
csrfToken: 249f3c20-649b-44de-9866-4ed72170d985

您需要一个外部站点无法读取的值(CSRF令牌),即HTML表单值或响应头中的值。

关于Origin头,旧的浏览器不支持它,而Flash有一些漏洞可以让客户端更改它。基本上,你会相信Adobe不会在未来搞砸任何事情……这听起来是个好主意吗?

确保每个HTTP请求都有CSRF保护

您只需要对有副作用的请求进行CSRF保护,比如改变状态或发送消息

孙胜泫
2023-03-14

总结

我对同源政策和CORS有一个误解,是@Bergi、@Neil McGuigan和@SilverlightFox帮我澄清的。

首先,@Bergi说的是

SOP不阻止发送请求。它确实阻止页面访问跨域请求的结果。

是一个重要的概念。我认为浏览器不会根据SOP限制向跨域发出请求,但这只适用于Monsur Hossain在这篇优秀教程中所说的“不那么简单的请求”。

跨来源请求有两种形式:

  • 简单请求
  • “不是那么简单的请求”(我刚刚编的一个词)

简单请求是指满足以下条件的请求:

  • HTTP方法匹配以下之一(区分大小写):
    • 头部
    • 获取
    • 岗位
    • 接受
    • 接受语言
    • 内容语言
    • 上次事件ID
    • 内容类型,但仅当该值为以下值之一时:
      • 应用程序/x-www-form-urlencoded
      • 多部分/表单数据
      • 文本/纯文本

      因此,带有内容类型应用程序/x-wan-form-urLencoted的POST将命中服务器(这意味着CSRF漏洞),但浏览器将无法访问该请求的结果。带有内容类型应用程序/json的POST是一个“不那么简单的请求”,因此浏览器将发出这样的prefilith请求

      如果服务器响应,例如:

      访问控制允许来源:http://trustedsite.com
      访问控制允许方法:GET、POST、PUT
      访问控制允许标头:内容类型
      内容类型:text/html;字符集=utf-8

      浏览器根本不会发出请求,因为

      XMLHttpRequest无法加载对预检请求的http://server.com/endpoint.响应未通过访问控制检查:“Access-Control-Allow-Origin”标头包含无效值“trustedsite.com”。因此不允许访问源' evilsite.com'。

      所以我认为尼尔是在谈论这个问题,他指出:

      同源策略仅适用于读取数据而不写入数据。

      然而,对于这个问题,我认为我向Bergi提出的origin header显式控制就足够了。

      关于我对Neil的回答,我并不是说那个答案就是我所有问题的答案,但它让我想起了关于SOP的另一个重要问题,那就是该策略仅适用于XMLHTTP请求。

      总之,我认为方程式

        < li >安全httpOnly cookie Origin标头中的TLS JWT检查没有XSS漏洞。

      如果API位于SilverlightFox所说的另一个域中,则是一个很好的替代方案。如果客户端与客户端在同一个域中,我会遇到不包含Origin头的请求的问题。同样来自cors教程:

      Origin 标头的存在并不一定意味着请求是跨源请求。虽然所有跨源请求都将包含 Origin 标头,但某些同源请求可能也包含一个标头。例如,Firefox 在同源请求中不包含 Origin 标头。但是Chrome和Safari在同源的POST/PUT/DELETE请求上包含一个Origin标头(同源GET请求将没有Origin标头)。

      Silverlight指出了这一点。

      剩下的唯一风险是客户端可以欺骗源标头以匹配允许的源,所以我正在寻找的答案实际上是这个

      更新:对于那些观看这篇文章的人,我怀疑使用 JWT 是否需要源标头。

      方程式为:

      • TLS JWT存储在请求头中的安全cookie JWT中没有XSS漏洞

      此外,前面的等式具有httpOnly cookie,但是如果您将客户端和服务器放在不同的域中(就像今天的许多SPA应用程序一样),这将不起作用,因为cookie不会随每个请求一起发送到服务器。因此,您需要访问存储在 cookie 中的 JWT 令牌并将其发送到标头中。

 类似资料:
  • 我有以下代码运行在localhost:3000和我的api运行在localhost:8020。如果我访问localhost:3000则向localhost:8020/user/refresh发出请求,以获取cookie中具有刷新令牌的新访问令牌,并使用新的访问令牌进行响应。我现在可以用获得的访问令牌提出另一个请求localhost:8020/user/delete. 但是为什么我能够以攻击者的身份

  • 我读过关于CSRF和不可预测的同步令牌模式是如何用来防止它的。我不太明白它是如何工作的。 让我们以这个场景为例: 用户使用以下表单登录到站点: 服务器还将令牌存储在会话中。发送请求时,它将表单数据中的令牌与会话中的令牌进行比较。 当黑客可以编写JavaScript代码时,如何防止CSRF: 发送GET请求到站点 接收包含请求表单的html文本。 在html文本中搜索CSRF令牌。 使用该令牌发出恶

  • 什么是CSRF CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。 那么CSRF到底能够干嘛呢?你可以这样简单的理解:攻击者可以盗用你的登陆信息,以你的身份模拟发送各种请求。攻击者只要借助少许的社会工程学的诡计,例如通过QQ等聊天软件发送的链接(有些还伪装成

  • 我们正在用运行在JBoss中的Java Spring/Hibernate后端构建一个应用程序。前端是AngularJS。 我们还没有在服务器端设置XSRF令牌。我们也没有(无论如何还没有)允许其他域访问我们的web资源的要求。 我想我会试着看看我们的站点是否容易受到XSRF攻击,所以我设置了一个恶意的webapp,使用Angular的$http.post()发布到我们真正应用程序的URL中。我登录

  • 我刚刚读了一篇文章 https://hasura . io/blog/best-of-practices-of-use-jwt-with-graph QL/ 总之,他们建议将JWT Access Token存储在内存中(例如在JavaScript中作为变量),并在HTTP-唯一Cookie中刷新Token。 他们说: 但是,通过通过刷新令牌间接地保持会话,我们防止了JWT令牌可能存在的直接CSRF

  • 所以我知道有很多关于CSRF的问题(因为我读过其中一些),但有一点我仍然不明白。让我们设想以下情况: > 我(使用cookies)登录到我的服务器,其中有一个带有“删除我的帐户”按钮的页面。我不想逼你。 我访问黑客的服务器: A.我的浏览器请求bad.html,其中包含JS,并定义了回调函数。它还有一个脚本,比如:(从而避免了同源政策问题) B.脚本"附加"浏览器将加载页面,然后调用hackerC