我是否需要jQuery .ajax()的CSRF令牌?

Nat*_*ers 28 security ajax jquery post csrf

所以我有一个PHP文件的基本.ajax()POST方法.

我需要哪些安全措施?

一些帖子提到使用您通过AJAX发送并在PHP文件中验证的隐藏MD5输入字段.这是一个足够好的方法吗?

Kei*_*ith 36

CSRF的风险是外部站点可以向您发送数据,用户浏览器将自动发送身份验证cookie.

您需要的是接收操作的某种方式(您的$.ajax()方法是将POST数据发送到),以便能够检查请求是否来自您网站上的其他页面,而不是外部网站.

有两种方法可以做到这一点,但建议的方法是在您可以检查的请求中添加一个令牌,黑客无法访问.

最简单的:

  • 登录时,创建一个长的随机字符串标记并将其保存到用户.
  • $.ajax()包含令牌的请求添加参数.
  • 根据请求检查令牌是否与您为用户保存的令牌匹配.
  • 如果令牌不匹配,则您有CSRF黑客攻击.

黑客无法访问您的数据库并且无法实际读取您发送给用户的页面(除非他们受到XSS攻击,但这是另一个问题)因此无法欺骗令牌.

对令牌而言,重要的是你可以预测(并验证)它并且黑客不能.

出于这个原因,最简单的方法是生成长而随机的东西并将其存储在数据库中,但您可以构建加密的东西.我不会只是MD5的用户名 - 如果CSRF攻击者弄清楚如何生成你的令牌你将被黑客入侵.

另一种方法是将令牌存储在cookie(而不是您的数据库)中,因为攻击者无法读取或更改您的cookie,只是让它们被重新发送.然后,您在HTTP POST数据中的令牌匹配cookie中的令牌.

您可以使这些变得更复杂,例如,每次成功使用时都会更改的令牌(防止重新提交)或特定于用户和操作的令牌,但这是基本模式.

  • 尽管[同源政策](https://en.wikipedia.org/wiki/Same-origin_policy)可以阻止此类行为,但用户如何从其他网站发布AJAX请求? (7认同)
  • @Songo并不是所有的浏览器都支持它.许多代理剥离标题并打破它.最后你可以从原点之外发布POST,所以即使你打算使用AJAX,也不意味着攻击者会这样做.基本上你应该有一个同源策略,但是因为它依赖于表现良好的浏览器,所以你不应该依赖它.使用CSRF令牌可以为您提供可以验证的内容,即使同源来源被绕过也是如此. (3认同)
  • @arleslie只是要清楚 - 将cookie与您的数据库进行比较根本不提供额外的安全性(您的身份验证cookie已经这样做了).重要的是将POST数据_either_中的标记与数据库中的标记或cookie中的标记进行比较.攻击者可以重新发送cookie但无法读取它,因此他们的恶意POST数据不能包含正确的值. (3认同)
  • @arleslie在CSRF攻击中黑客_无法看到你的cookie_,他们无法解析你的请求或阅读你发送或收到的内容.如果他们已经破坏了您的计算机,那么您无能为力,但CSRF攻击要简单得多:攻击者没有破坏您的计算机,但可以欺骗您将其有效负载提交到您已登录的站点.他们无法读取您的Cookie,但他们可以使用其内容重新发送.您可以通过确保POST(而不仅仅是cookie)的内容中包含可验证的数据来阻止此攻击. (3认同)
  • @arleslie一个典型的例子是我(作为黑客)工艺并让你访问的页面 - 一旦在该页面上我向Facebook提交了一个POST.我对你的Facebook cookie,甚至你的名字一无所知,但POST会发送你的FB auth cookie以及我的指示,喜欢并在你的墙上分享我的黑客页面(这实际上发生在Facebook上).在CSRF攻击中,我不会拦截您对Facebook的请求 - 我只是依靠您的浏览器再次发送它. (2认同)