2014-07-16 28 views
3

我有AJAX代码,它向POST请求发送到Django 1.6.4应用程序。该视图通过django.middleware.csrf.CsrfViewMiddleware启用CSRF保护。如果我没有通过cookie但通过HTTP_X_CSRFTOKEN,则失败。Django 1.6 HTTP_X_CSRFTOKEN标头被忽略,如果csrf cookie丢失

我在查看django.middleware.csrf.CsrfViewMiddleware的代码,我看到在第161行,它检查从cookie中获取它后是否if csrf_token is None:。如果它是None,它会返回。之后才会检查csrfmiddlewaretoken param和HTTP_X_CSRFTOKEN请求标头。这看起来不正确,只有在检查所有可能的地方找到它的位置后,才应该检查缺少的csrf_token值。

其他人有类似的问题?我看到这个不正确吗?

回答

0

如果您使用的是jQuery,则可以创建包含csrf标记的beforeSend函数。 Django CSRF了解更多信息。

请注意,Django寻找标头X-CSRFToken而不是HTTP_X_CSRFTOKEN。 至少这是我在调试代码时遇到的问题。 (我还检查django.middleware.csrf.CsrfViewMiddleware此)


if csrf_token is None是Django的做了额外的检查。 (从if语句的注释说明。

没有CSRF的Cookie。对于POST请求,我们坚持一个CSRF饼干, 在这样就能避免所有CSRF攻击,包括登录 CSRF。

我认为(不知道),没有一个统一的检查只验证从一个AJAX POST请求头, 和Django会做检查,以防止任何形式的CSRF攻击。

+0

我知道'beforeSend'并正在使用它。虽然HTTP头称为X-CSRFToken,但Django通过预先设置HTTP_使其可用作HTTP_X_CSRFTOKEN。请参阅https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.META。但是,这不是我的问题。我提供了标题值,Django甚至没有看到它(请看我在原帖中引用的Django源文件) –

+0

已更新我的答案。 – Eagllus

2

我觉得混乱可能是CSRF cookie和HTTP头存在于比较的两侧。换句话说,为了防止跨站请求伪造攻击,Django的比较:

CSRF cookie值与POST令牌值( “csrfmiddlewaretoken”)

(或)

CSRF cookie值对HTTP头值(” HTTP_X_CSRFTOKEN“)

这就是为什么cookie是总是需要。使用HTTP_X_CSRFTOKEN标题是替代在POST数据中设置标记,而不是cookie的替代品。