跨站点请求伪造(CSRF)保护

跨站点请求伪造,也称为一键式攻击或会话骑行,缩写为 CSRF 或 XSRF,是一种恶意利用网站,其中未经授权的命令从网站信任的用户传输。学到更多

要启用 CSRF 保护,请将 CsrfViewMiddleware 添加到中间件类。默认情况下启用此中间件。

# settings.py
MIDDLEWARE_CLASSES = [
    ...
    'django.middleware.csrf.CsrfViewMiddleware',
    ...
]

此中间件将在传出响应的 cookie 中设置令牌。每当传入的请求使用不安全的方法(除 GETHEADOPTIONSTRACE 之外的任何方法)时,cookie 必须匹配作为 csrfmiddlewaretoken 表单数据或 X-CsrfToken 标头发送的标记。这可确保发起请求的客户端也是 cookie 的所有者,并且通过扩展,还可以确认(经过身份验证的)会话。

如果通过 HTTPS 发出请求,则启用严格的引荐来源检查。如果 HTTP_REFERER 标头与当前请求的主机或 CSRF_TRUSTED_ORIGINS 中的主机( 1.9 中的新主机)不匹配,则拒绝该请求。

使用 POST 方法的表单应在模板中包含 CSRF 令牌。{% csrf_token %} 模板标记将输出一个隐藏字段,并确保在响应中设置 cookie:

<form method='POST'>
{% csrf_token %}
...
</form>

使用 @csrf_exempt 装饰器可以免除不易受 CSRF 攻击的个人观点:

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def my_view(request, *args, **kwargs):
    """Allows unsafe methods without CSRF protection"""
    return HttpResponse(...)

虽然不推荐,但如果你的许多视图不容易受到 CSRF 攻击,则可以禁用 CsrfViewMiddleware。在这种情况下,你可以使用 @csrf_protect 装饰器来保护单个视图:

from django.views.decorators.csrf import csrf_protect

@csrf_protect
def my_view(request, *args, **kwargs):
    """This view is protected against CSRF attacks if the middleware is disabled"""
    return HttpResponse(...)