Django中CSRF防护源码解析:

Django中如何防范CSRF

Django使用专门的中间件(CsrfMiddleware)来进行CSRF防护。具体的原理如下:

1.它修改当前处理的请求,向所有的 POST 表单增添一个隐藏的表单字段,使用名称是 csrfmiddlewaretoken ,为当前会话 ID 加上一个密钥的散列值。 如果未设置会话 ID ,该中间件将不会修改响应结果,因此对于未使用会话的请求来说性能损失是可以忽略的。

2.对于所有含会话 cookie 集合的传入 POST 请求,它将检查是否存在 csrfmiddlewaretoken 及其是否正确。 如果不是的话,用户将会收到一个 403 HTTP 错误。 403 错误页面的内容是检测到了跨域请求伪装。 终止请求。

该步骤确保只有源自你的站点的表单才能将数据 POST 回来。 

 

另外要说明的是,未使用会话 cookie 的 POST 请求无法受到保护,但它们也不 需要 受到保护,因为恶意网站可用任意方法来制造这种请求。为了避免转换非 HTML 请求,中间件在编辑响应结果之前对它的 Content-Type 头标进行检查。 只有标记为 text/html 或 application/xml+xhtml 的页面才会被修改。

Django的CSRF防御方法采用的是在请求中添加toke并验证方法,源码分析如下: 如果有form提交时,验证csrftoken,django在打开这个页面时就会将csrftoken存在cookie中,当用户提交表单时进行匹配,如果相同则证明是一个安全提交。 csrftoken的生成方式如下:

md5_constructor("%s%s" % (randrange(0, _MAX_CSRF_KEY), settings.SECRET_KEY)).hexdigest()

设置csrftoken:

response.set_cookie(settings.CSRF_COOKIE_NAME, request.META["CSRF_COOKIE"], max_age = 60 * 60 * 24 * 7 * 52, domain=settings.CSRF_COOKIE_DOMAIN)
  • 1

csrftoken与cookie中的token比较:

if not constant_time_compare(request_csrf_token, csrf_token):

如果不一致返回403错误 注意:表单内必须加入csrf_token的tag,否则站内提交也会被阻止,除非添加@csrf_exempt装饰器

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011715678/article/details/48561181

posted on 2018-05-29 19:02  王大拿  阅读(263)  评论(0)    收藏  举报

导航