0

我是一个网络应用程序新手。我知道在 SO 中提出了 XSRF 保护问题,但这些问题特定于特定语言(例如 RoR/Python)或库(jQuery)。我想知道如何在我的 Web 应用程序中实现 XSRF 保护。

我的理解是,XSRF 保护依赖于使用唯一的随机令牌,在发出 HTTP 请求时必须对其进行身份验证。我有以下问题:

  1. 何时应该初始化身份验证令牌?是否应该在页面加载时设置(即 GET 请求)?
  2. 令牌应该在哪里初始化?是否应该在输入字段、cookie 或请求标头中设置它们?这个随机值是如何产生的?我如何保持这个值以便用于比较?
  3. 何时应验证身份验证令牌?如何比较身份验证令牌?如何将这些令牌与我保留的令牌进行比较?

同步表单请求与 AJAX 请求的设置有区别吗?

4

2 回答 2

2

何时应该初始化身份验证令牌?

在会话期间,用户第一次到达包含您希望保护免受 CSRF 攻击的任何表单的页面。

是否应该在页面加载时设置(即 GET 请求)?

它应该在生成 HTML 时嵌入到表单中。

是否应该在输入字段、cookie 或请求标头中设置它们?

隐藏的输入。

使用 cookie 会错过重点(即它来自页面并且不会保留在浏览器中)。额外的标头只能在使用 XHR 时起作用,使用通用方法。

这个随机值是如何产生的?

带有随机数发生器

我如何保持这个值以便用于比较?

会话

何时应验证身份验证令牌?

作为授权步骤的一部分。

如何比较身份验证令牌?如何将这些令牌与我保留的令牌进行比较?

if ( $request->paramaters->{csrf} eq $session->data->{csrf} )

同步表单请求与 AJAX 请求的设置有区别吗?

不。您仍然有一个会话,并且您仍然有一块 POST 数据作为令牌。

于 2013-08-03T09:24:51.547 回答
0

我不会谈论您必须遵循的特定解决方案,因为有很多,我将讨论主要思想,您可以根据需要实施它。

防止 XSRF 的关键思想是将随机令牌存储在其他域的代码无法访问的地方(例如 cookie)。您可以在服务器端生成此令牌并指示浏览器在整个会话中将其存储在本地。(不需要在服务器端保留任何东西)

每当您执行请求时,发送:

  • 您存储中的令牌(如果您使用 cookie,浏览器将自动发送它)。
  • 与您的请求中存储的令牌相同(无论是作为标题还是在正文中使用隐藏字段,具体取决于服务器代码获取它的方式

在服务器端,服务器将检查匹配。

jquery 中的示例代码(带有 jquery cookie 插件):

$.ajax({
   url:"someurl",
   data:{token:$.cookie('token')}
});

读取cookie的能力证明这是来自你的域,而不是外部域 实现这个机制的方法有很多种(不需要拘泥于特定的方案),只要他们坚持主旨即可:

  • 将秘密令牌存储在来自其他域的位置代码中的浏览器中无法读取它。
  • 将秘密令牌和相同的令牌从浏览器发送到您的服务器。发送相同令牌的能力证明这不是 XSRF 请求。

我如何保持这个值以便用于比较?

我们可以将其存储为 cookie 或会话变量。就个人而言,我更喜欢 cookie,因为:

  • 减少服务器端的内存消耗。
  • 我们不需要在每个生成的 HTML 文件中都包含该令牌,以便浏览器将其发回。

同步表单请求与 AJAX 请求的设置有区别吗?

不,只要您可以通过在 request中发送相同的令牌来证明这不是 XSRF 请求。令牌在哪里(隐藏字段、自定义标题、..)并不重要。对于表单,人们通常将其作为隐藏字段发送。

于 2013-08-03T09:31:38.357 回答