csrf 令牌正在显示?

5 django csrf django-csrf

我是 Django 和 csrf 令牌的新手,所以这是一个全新的问题。我在 detail.html 上有一个简单的复选标记框:

<form action="/results/" method="post">{% csrf_token %}
<input type="checkbox" value="1" name="artists">
<p><input type="submit" value="Send" /></p>
</form>
Run Code Online (Sandbox Code Playgroud)

results.html 看起来像这样:

<ul>
{% for choice in poll %}
    <li>{{ choice }} </li>
{% endfor %}
</ul>
Run Code Online (Sandbox Code Playgroud)

views.py 看起来像这样:

from django.shortcuts import render_to_response
from django.core.context_processors import csrf

def handle(request):
    artists = {}
    c = {}
    c.update(csrf(request)) 
    if request.method == 'POST':
        artists = request.POST.getlist('artists')
    return render_to_response('polls/results.html', {'poll': artists})
Run Code Online (Sandbox Code Playgroud)

urls.py 看起来像这样:

from django.conf.urls import patterns, url
from django.conf import settings

urlpatterns = patterns('',
    url(r'^detail/$', 'django.views.generic.simple.direct_to_template', {'template': 'polls/detail.html'}),
    url(r'^results/$', 'polls.views.handle'),
)
Run Code Online (Sandbox Code Playgroud)

当我加载“detail.html”和viewsource时,我看到:

<form action="/results/" method="post"><div style='display:none'><input type='hidden' name='csrfmiddlewaretoken' value='TVidKbDr1SCJUWIMWpPecN5tR862Chbo' /></div>
<input type="checkbox" value="1" name="artists">
<p><input type="submit" value="Send" /></p>
</form>
Run Code Online (Sandbox Code Playgroud)

我有两个问题:

  1. 我应该在 viewsource 中看到 csrf 令牌吗(即 value='TVidKbDr1SCJUWIMWpPecN5tR862Chbo')?我认为它的全部意义在于攻击者无法看到这个独特的价值。
  2. 在views.py 中,我不应该在某处传递变量'c' 吗?当我没有通过'c'时,一切都按预期工作。我只是不知道如何使用它。

Chr*_*att 6

  1. 不,目的不是让攻击者看不到价值。CSRF(跨站点请求伪造),顾名思义,旨在防止第三方站点或客户端匿名将数据发布到您的表单处理程序视图。CSRF 令牌在页面加载时生成,并且必须在提交表单时在响应视图中匹配。第三方实体无法提供匹配代码(因为它是在 Django 内部生成的),因此无法发布表单。它是隐藏字段的事实仅仅是为了不向用户呈现,因为这是他们不需要知道或更改的信息。它用于任何类型的保护的想法是疯狂的,因为任何知道足够尝试攻击您的站点的人也知道如何查看源代码。

  2. 我不确定您是从哪里选择该代码的,但首先它是不必要的。Django 的默认行为是将 CSRF 令牌添加到上下文中。如果您使用csrf_exempt装饰器在视图上禁用 CSRF 保护,则只需要手动执行此操作,因为您需要 CSRF有条件地保护视图。但是,如果您确实需要这样做,则c需要将该变量添加到传递给的上下文中render_to_response

    c = {'poll': artists}
    c.update(csrf(request)
    
    ...
    
    return render_to_response('polls/results.html', c)
    
    Run Code Online (Sandbox Code Playgroud)