这可能听起来像一个愚蠢的问题。我想清楚这一点。如果令牌首先发送到客户端并且客户端发回相同的令牌,csrf令牌如何帮助识别跨站点请求?恶意客户端不会从服务器获得响应。
如果我们在发送令牌时检查原点,那么令牌检查事件似乎不是多余的吗?
我们如何确保服务器只向授权客户端提供令牌,以及将令牌从服务器传输到客户端的最佳做法是什么?
我曾问过相关问题this,但需要更深入了解它。所以在这里问一个不同的问题。
希望通过示例获得一些答案。
提前谢谢
答案 0 :(得分:0)
CSRF基本上是关于攻击者通过Cookie在浏览器中工作的方式利用用户的现有会话。根本问题在于,无论请求来自哪个(来源,即域名),都会向请求发送cookie,唯一重要的是到> EM>。因此,如果有用户登录到应用程序(具有会话cookie),攻击者可能会尝试让该用户访问他的恶意网站,攻击者可以从该网站向用户提出对应用程序域的请求凭证(通过完全将用户发布到应用程序,或通过创建ajax请求更巧妙地)。
请注意,这仅适用于应用程序中的身份验证基于浏览器自动发送的内容,最明显的是会话cookie,但是例如基本的http身份验证或客户端证书身份验证也可能存在漏洞。此外,CSRF仅适用于更改某些内容(状态或数据)的请求。
扮演一个角色有一个重要的事情,相同的原始政策(SOP)是浏览器。有点简化,这意味着如果从一个域(或更确切地说:源)下载某些内容,则另一个域将无法访问。
因此,为了防止上述攻击并防止攻击者在自己的域上让用户向用户登录的应用程序发送不需要的请求,可能会有几种不同的策略。
应用程序生成一个csrf令牌,将其存储在用户的会话(服务器端)中,并通过例如将其以隐藏字段中的每种形式写入客户端,或者将其发送到客户端Javascript可以从中读取并添加到请求的字段。这是有效的,因为他的域上的攻击者无法使用用户会话中的有效令牌创建表单或请求,并且攻击者也无法从应用程序页面读取令牌。当然,攻击者可以尝试下载申请表以获取令牌,但随后他需要凭据。攻击者需要有效的用户会话和相应的csrf令牌。攻击者可能有自己适当的帐户登录,但他无论如何都可以执行操作。或者他可能有一个csrf令牌,但要么是未经身份验证的,要么是较低的权限帐户。但他不能同时拥有这两者,这就是重点。
因此,这种保护基本上验证了请求来自合法应用程序实际呈现的源,而不是其他人。
请注意,在这种情况下,在cookie中设置令牌毫无意义,因为cookie将像会话cookie一样自动发送。
另一种策略是生成令牌,并将其设置为客户端的cookie。然后,客户端从cookie中读取令牌,并将相同的令牌作为请求头发送。服务器仅比较请求标头和cookie是否包含相同的标记。这是有效的,因为攻击者无法从不同来源的cookie集中读取应用程序令牌(请参阅上面的SOP),但合法域上的应用程序可以。因此,有效发送请求的客户端证明它正在合法的应用程序域上运行。这样做的好处是应用程序是无状态的,不需要会话。缺点是安全性稍差。
(有趣的是,在这种情况下,令牌甚至可以在客户端生成,它仍然有效,因为他自己的域上的攻击者无法设置或读取应用程序域cookie,但它肯定不太安全,因为它是加密在浏览器中操作。)
正如您所正确指出的,另一种策略可能是检查请求的引用者或来源。它基本上有效,但被认为不太安全。虽然双重发布对于许多应用程序来说足够安全,但引用/原点检查通常不是。我认为它有一个强大的历史元素,但它仍然 不太安全。
问题有很多方面,有些是我想到的:
因此,出于这些原因,仅仅检查引用/来源不是很强大,应该有另一层保护。
谷歌在Chrome中的新发明是Cookie的SameSite
属性(除了已存在且广泛使用的httpOnly
和secure
Cookie属性)。截至目前,它仅受Chrome支持,而不支持其他浏览器。
如上所述,潜在的问题是cookie(即会话cookie)基于请求目标而不是源而被发送到服务器。这意味着如果attacker.com服务器向用户提供页面并且该页面从浏览器向legitapp.com发送帖子请求,则legitapp.com设置的任何cookie都将发送到legitapp.com。因此,如果用户登录legitapp.com访问attacker.com,则可以利用现有会话。
这由SameSite cookie attribute更改,这使得在原始域与目标域不同的情况下不会发送cookie。它可以设置为严格的'或者' lax',它基本上决定了GET请求行为,但是其中任何一个都会阻止CSRF 非GET请求。