安全开发 | 如何让Django框架中的CSRF_Token的值每次请求都不一样
前言
用过Django 进行开发的同学都知道,Django框架天然支持对CSRF攻击的防护,因为其内置了一个名为CsrfViewMiddleware的中间件,其基于Cookie方式的防护原理,相比基于session的方式,更适合目前前后端分离的业务场景,但美中不足的是,其生成的csrf_token在一个session周期中是不变,这对于一些特定的业务场景,显然有点遗憾。
为了弥补这个遗憾,本文介绍一种不用修改CsrfViewMiddleware中间件源码的方式,实现基于请求的csrf_token更新方式,详文如下。
实现过程
1、Django csrf 校验的两个场景
在业务场景中,有两种不同的csrf防护场景,一种是基于Form 表单提交数据的防护,一种是基于ajax 异步请求数据的防护。
对于Form 表单,可以通过在表单中内置`{% csrf_token %}` 实现在提交数据时一起携带csrf_token提交上去,从而通过后端csrf 校验。
这里顺便提下 Django模板引擎是如何渲染`{% csrf_token %}`的,其实就是将`{% csrf_token %}` 替换成csrf_input的返回值(这点可从Django 模板引擎源码中找到),如下:

而get_token则是从request.META['CSRF_COOKIE']中获取:

对于ajax 请求,需要在提交请求的时候,添加一个名为x-csrftoken的头部(这个头部是Django源码中内定的),值为从cookie中提取的指定name的值,这个name可自定义,比如下图为`csrf-bastion`:

2、Django csrf token 的生成流程
主要关注下CsrfViewMiddleware 中间件的process_view和process_response。
process_view的主要功能之一就是从请求的cookie中提取指定name的(通过settings.CSRF_COOKIE_NAME指定)cookie值为:csrf token,然后赋值给request.META['CSRF_COOKIE'],如果从请求头中提取不到,则重新生成,如下图:

process_response 中会有更新csrf token cookie的功能,如下:

3、 通过在视图中修改request.META['CSRF_COOKIE']值实现csrf token 的更新
通过1和2我们就可以知道只要在在response返回之前更新request.META['CSRF_COOKIE']的值,便可以实现每次请求的csrf token 都不一样,当然可以通过修改CsrfViewMiddleware中间件源码的方式实现,不过这种方式的入侵性太大,最好的选择是在视图中修改,因为视图处理流程是在response之前进行,如下:

这里的rotate_token则是CsrfViewMiddleware 中间件提供的更新csrf token的接口,如下:

总结
本文提到的这个方法确实可以实现基于请求对csrf_token值进行更新,而不是原先的基于session的,这样更新之后,对于ajax请求倒是没有什么问题,不过对于From表单中csrf_token值的更新是需要进行后端渲染更新的,对于前后端分离的请求,这个不足是可以让后端提供个token 获取接口来实现前端页面中form表单的csrf_token值更新实现,当然也可以对form表单的提交行为进行监听,然后异步提交,这样直接走ajax那条路线,就没啥问题了。
安全开发 | 如何让Django框架中的CSRF_Token的值每次请求都不一样的更多相关文章
- Windows上python开发--2安装django框架
Windows上python开发--2安装django框架 分类: 服务器后台开发2014-05-17 21:22 2310人阅读 评论(2) 收藏 举报 python django 上一篇文章中讲了 ...
- Python的Django框架中的Cookie相关处理
Python的Django框架中的Cookie相关处理 浏览器的开发人员在非常早的时候就已经意识到. HTTP's 的无状态会对Web开发人员带来非常大的问题,于是(cookies)应运而生. coo ...
- Django框架中logging的使用
Django框架中logging的使用 日志是我们在项目开发中必不可少的一个环节,Python中内置的logging已经足够优秀到可以直接在项目中使用. 本文介绍了如何在DJango项目中配置日志. ...
- Django框架中的Context使用
Django框架中的Context使用 2017年11月09日 20:01:09 aweilark 阅读数:1113 转载自:http://www.aichengxu.com/python/606 ...
- 分布式队列celery 异步----Django框架中的使用
仅仅是个人学习的过程,发现有问题欢迎留言 一.celery 介绍 celery是一种功能完备的即插即用的任务对列 celery适用异步处理问题,比如上传邮件.上传文件.图像处理等比较耗时的事情 异步执 ...
- Python的Django框架中forms表单类的使用方法详解
用户表单是Web端的一项基本功能,大而全的Django框架中自然带有现成的基础form对象,本文就Python的Django框架中forms表单类的使用方法详解. Form表单的功能 自动生成HTML ...
- Python的Django框架中的Context使用
Python的Django框架中的Context使用 近期整理些Python方面的知识,一旦你创建一个 Template 对象,你能够用 context 来传递数据给它. 一个context是一系列变 ...
- Django框架中使用Echart进行统计的SQL语句
最近想用Echart做数据统计的图形显示,数据来源是MySQL数据库,自然需要根据不同的搜索条件筛选出表中的数据,用比较多的就是时间的参数吧! 常用的mysql时间的条件进行检索的SQL语句: 数据表 ...
- Python中的Django框架中prefetch_related()函数对数据库查询的优化
实例的背景说明 假定一个个人信息系统,需要记录系统中各个人的故乡.居住地.以及到过的城市.数据库设计如下: Models.py 内容如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 1 ...
随机推荐
- Ionic Js十三:平台
$ionicPlatform $ionicPlatform 用来检测当前的平台,以及诸如在PhoneGap/Cordova中覆盖Android后退按钮.  
- 最详细的vue-cli安装教程 &^没有之一 ^& 大神亲测。。╮( ̄▽  ̄)╭
这里介绍使用git安装,电脑自带命令行依然可以使用进行安装 第一步 node环境安装 1.1 如果本机没有安装node运行环境,请下载node 安装包进行安装 1.2 如果本机已经安装node的运行换 ...
- 标准c库函数与Linux下系统函数库 区别 (即带不带缓冲区的学习)
我们都知道,C语言在UNIX/Linux系统下有一套系统调用(系统函数),比如文件操作open().close().write().read()等,而标准C语言的库函数中也有一套对文件的操作函数fop ...
- 内核启动文件系统后第一个执行的文件(inittab启动脚本分析)
Linux 开机脚本启动顺序: 第一步:启动内核 第二步:执行init (配置文件/etc/inittab) 第三步:启动相应的脚本,执行inittab脚本,并且执行里面的脚本/etc/init.d ...
- C#中的特性 (Attribute) 入门 (二)
C#中的特性 (Attribute) 入门 (二) 接下来我们要自己定义我们自己的特性,通过我们自己定义的特性来描述我们的代码. 自定义特性 所有的自定义特性都应该继承或者间接的继承自Attribut ...
- luoguP4466 [国际集训队]和与积 莫比乌斯反演
自然想到枚举\(gcd(a, b)\),不妨设其为\(d\),并且\(a = di, b = dj(a > b)\) 那么\(\frac{ab}{a + b} = \frac{dij}{i + ...
- hdu 4557 暴力
题意: 作为2013年699万应届毕业生中的一员,由于宏观经济的不景气,小明在毕业当天就华丽丽地失业了! 经历了千难万苦的求职过程,小明特别能理解毕业生的就业之难,所以,他现在准备创建一家专门针对IT ...
- hdu 4540 dp
题意: 假设: 1.每一个时刻我们只能打一只地鼠,并且打完以后该时刻出现的所有地鼠都会立刻消失: 2.老鼠出现的位置在一条直线上,如果上一个时刻我们在x1位置打地鼠,下一个时刻我们在x2位置打地鼠,那 ...
- Node.js学习笔记(2) - Node.js安装及入门hello world
今天来简单的记录一下Node.js的安装配置以及简单的入门 一.Node.js的安装 1.windows下的安装 windows下的安装很简单,只需要去官网http://nodejs.org中,找到w ...
- OpenVPN分配静态IP以及同一网段内IP个数(64个)
说明:简单的来说,同一网段内可用的IP数量只有64个:(不一定正确)最直接的解释就是每个客户端占用两个IP,因为根据IP掩码位/30得知可用的IP就是两个.对于为什么只有64个,下面是官方的解释. 解 ...