以下引用来自http://www.codinghorror.com/blog/2008/10/preventing-csrf-and-xsrf-attacks.html
当用户访问网站时,该网站应生成一个 (加密强)伪随机值并将其设置为cookie 在用户的机器上。该网站应要求提交每份表格 将此伪随机值包括为表单值,也包括 饼干价值。当POST请求发送到站点时,请求 只有表格值和cookie值才应被视为有效 是相同的。当攻击者代表用户提交表单时,他 只能修改表单的值。攻击者无法阅读任何内容 从服务器发送的数据或修改cookie值,根据同源 政策。这意味着攻击者可以发送他想要的任何值 使用表单,他将无法修改或读取存储的值 饼干。由于cookie值和表单值必须是 同样,攻击者将无法成功提交表单,除非 他能猜出伪随机值。
上述方法通过比较cookie和表单中的伪随机值来防止CSRF攻击。但是,为什么还需要使用表单返回值?我假设表单和cookie具有相同的加密值,它们将返回到服务器。并且服务器通过解密该值来验证它。
因此,即使该值仅由cookie返回,服务器也可以对其进行解密并验证请求。使用表单返回加密值的目的是什么?
答案 0 :(得分:43)
好的,让我们将问题分解为原子问题以便更好地理解:
这是什么CSRF?
这是一种Web应用程序漏洞。在最基本的层面上,CSRF的原因是浏览器不理解如何区分用户是否故意执行某项操作(例如通过单击表单上的按钮,或单击超链接等)。 )或者如果用户在不知情的情况下执行了操作(比如说用户访问了某个域中的某个页面,请说bad.com,bad.com在用户登录good.com时向good.com/some_action发送了请求)。
那么CSRF的影响是什么
现在让我们用facebook.com取代上面的good.com。并且假设当登录到facebook.com的用户在他的墙上发布评论时,会发送一个HTTP GET请求,其格式为: https://facebook.com/postComment?userId=Abhinav_123&comment=HiIAmAbhinav。
现在让我们假设用户在登录facebook.com时访问bad.com上的某个页面。现在bad.com属于攻击者,他在bad.com上编码了以下内容:
<img src="https: //facebook.com/postComment?userId=Abhinav_123&comment=I_AM_AN_IDIOT>
现在,只要用户的浏览器在bad.com上加载此页面的内容,请求也会被发送到facebook.com:
https://facebook.com/postComment?userId=Abhinav_123&comment=I_AM_AN_IDIOT
因为浏览器尝试呈现img标记。为此,它需要获取src中指定的资源,因此它发送上述HTTP GET请求。基本上,攻击者实际上可以代表用户向facebook.com提交请求,而他实际上并不知道这一点。
现在有什么可能阻止这种攻击?
如果只是某种方式来确定用户是否故意提出请求。所以要做到这一点,反CSRF令牌就出现了。它只是服务器生成的随机唯一字符串(在上面的示例中为facebook.com),并发送给用户并在用户的浏览器中设置为cookie。现在,对于涉及一些敏感操作的每个请求(比如在上面的我们的facebook示例中发布评论),浏览器将在执行操作之前发送此随机字符串以及请求和服务器将验证随机字符串是否是它具有的那个是否发送到浏览器。
这个想法是攻击者不会知道这个随机字符串。因此,即使攻击者创建了如上所示的img src,并且用户访问bad.com,也不会执行(在上面的示例中发布评论)的操作,因为要执行的操作,除了URL之外,还需要一个额外的东西,即攻击者没有的随机字符串。
但是,再次在cookie中设置此随机字符串有一个巨大的缺陷
由于Cookie的设计方式以及浏览器处理Cookie的方式,在Cookie中设置此随机字符串(反CSRF令牌)将无法满足我们的目的。根据设计,cookie会随着客户端向该服务器发出的每个请求自动发送到服务器(简单地说,为了简单起见,省略了详细信息。有关详细信息,请参阅:RFC2965)
因此,在上面的示例中,攻击者并不需要知道随机字符串。发布评论操作仍将完成,因为一旦用户访问bad.com并加载帖子评论URL(如上所述),随机反CSRF令牌(存在于cookie中)将自动伴随请求。
那么解决方案是什么?
服务器(facebook.com)不需要将反CSRF令牌放在cookie中,而是需要将其作为隐藏参数放在表单中,并在用户请求发布此表单的注释时生成(持有反... CSRF令牌也应该发布。
现在攻击者无法代表用户执行此敏感操作(除非他以某种方式找到随机的反CSRF令牌本身)
现在遇到登录CSRF和双提交cookie的问题
很多时候,网站会通过部署某种形式的anti_CSRF令牌架构来保护自己免受CSRF攻击。但很多时候网站并不关心保护他们的登录表格免受CSRF攻击。为什么? - 因为即使登录表单容易受到CSRF攻击,并且攻击者试图通过他的域(bad.com)向good.com(facebook.com)构建登录请求来利用它,用户仍然需要输入他的有效凭据登录到facebook.com。这些凭据仅适用于真实用户而非攻击者,因此攻击者无法构建成功的登录请求。
那么攻击者在这里的攻击机会是什么?
攻击者可以在facebook.com上创建自己的帐户。他现在拥有一套有效的证件。现在,他使用登录凭据和他的域(bad.com)将登录请求构建到facebook.com。 现在,当用户访问bad.com页面时,用户将登录到我的帐户。我作为攻击者可以稍后看到用户在该帐户上执行的所有活动也可能泄露敏感信息(例如,如果用户选择发送新的朋友请求,则发送朋友请求,发送给某人的消息,如果用户这样做的话登录到我的帐户后。所有这些可能性取决于用户是否确信他已登录到自己的帐户,攻击者可以通过使他自己的Facebook页面看起来与受害者的关系一样来照顾他们。尽可能让他相信这是他的帐户)
现在针对此的缓解技术是什么?
这是我们现在需要的双提交cookie。
这究竟是什么意思
双重提交cookie定义为在cookie和请求参数中发送随机值,服务器验证cookie值和请求值是否相等。
它如何帮助减轻攻击?
根据双cookie的实现原理,当匿名用户(未登录用户)访问登录页面时,服务器在用户的浏览器中设置带有一些随机字符串的cookie,并且也设置相同的一个请求参数(比如一个表单隐藏字段)。当用户提交登录请求时,这些内容会随请求一起提交 - 用户凭据,隐藏表单字段中的随机字符串以及包含随机字符串的cookie(当然会自动发送)。
现在,攻击者可以访问自己的凭据,即服务器在cookie和隐藏表单字段中为攻击者设置的随机字符串。当攻击者将此精心设计的登录请求发送给用户(受害者),并且用户尝试发出此请求时,该用户仍未登录,并且到目前为止该服务器的匿名用户。因此,服务器将使用不同的(来自攻击者的)随机值在用户的浏览器上设置cookie。现在,当用户通过攻击者制作的链接发出登录请求时,该请求将包含攻击者的凭据,即隐藏表单字段中的攻击者随机字符串,但用户&#39 ; cookie中的随机字符串(来自用户的浏览器)。现在,当此请求到达服务器时,cookie中的随机字符串和隐藏的表单字段将不匹配,因此将被标记为异常并进行相应处理。
所以这就是用表格返回加密值的原因。希望它能清除这个概念。
答案 1 :(得分:8)
每次请求都会自动发送Cookie,无论请求是由原始网站还是第三方网站发起的。这就是为什么单独的cookie不足以满足每个请求都包含它的原因。
但是,通过在请求本身中也使用令牌,攻击站点不能再生成有效请求,因为它们无法保留用户的令牌。