Django作为一个重量级框架,其已经事先为我们内置了很多安全模块,CSRF中间件就是其中之一。那么究竟什么是CSRF,其中间件工作原理是怎样的,我们又应该如何去使用CSRF呢。这一篇文章我们一起来深入学习一下。
我是T型人小付,一位坚持终身学习的互联网从业者。喜欢我的博客欢迎在csdn上关注我,如果有问题欢迎在底下的评论区交流,谢谢。
文章目录
什么是CSRF
CSRF,全程Cross Site Request Forgery,中文名“跨站请求伪造”。
前面学习三种会话技术的时候,我们了解了cookie和session(session也借助于cookie)。假设用户小付在某网站www.alotofmoney.com
已经经过认证获得了cookie或者session存储在本地浏览器,此时坏人发给小付一个网址,里面有个链接,点击以后会访问www.alotofmoney.com
的一个汇款API。因为已经经过了认证,所以受害者小付此时用刚才同样的浏览器访问这个API是会成功的,即使这并不是他的本意。
这种利用已经被服务器信任的浏览器,伪造用户请求的攻击方式,就叫CSRF。
CSRF的防范策略
目前有下面三种方式可以用来防范CSRF:
- 利用token
既然存储在浏览器中的cookie那么轻易被利用,那么就不用浏览器中的cookie了,利用本地数据库或者文件中记录的token信息来访问网站。关于token的使用可以参考我的另一篇博客《【Django 014】Django2.2会话技术之Token》
- 确认referer
在网页跳转的时候,request头中会带有一个referer,在处理敏感请求的时候,referer应该和目标url属于同一个域名。而CSRF中的referer却是坏人自己的网站,所以会失败。但是类似爬虫可以修改请求header一样,难保坏人不去手动修改这个字段。所以这个检测手段简单但并不一定可靠。
- 给网页添加特殊cookie
这是Django中使用的方法。可以在网页中添加一些代码,使得该网页在发送请求的时候会带上一些特殊cookie,这个cookie在服务端可以被验证。如果验证通过标明是受信任的网页,反之则访问被拒绝。
Django中的CSRF中间件
下面重点来看看Django中实现CSRF的中间件。
新建的项目就会自带下面的这个中间件
'django.middleware.csrf.CsrfViewMiddleware',
点进去看看源码。
类的结构
先看下类大概长啥样
和所有中间件一样,继承自MiddlewareMixin
,是一个类装饰器。除了魔术方式以外一共还有7个方法
- process_request
- process_view
- process_response
这是我们前面说的5个切点中的3个,前两个在请求阶段,最后是在返回阶段。
- _accept
- _reject
- _get_token
- _set_token
这4个方法用来被上面3个切点调用,完成特定功能。以单下划线开头,表示不建议被外部访问。
下面就从数据流的方向依次看看这3个切点完成的功能。
process_request
其代码如下
def process_request(self, request):
csrf_token = self._get_token(request)
if csrf_token is not None:
# Use same token next time.
request.META['CSRF_COOKIE'] = csrf_token
本质就是从请求中拿到一个csrf_token
的值,如果能拿到,放到请求的元数据中供后面使用。
重点看下用来获取这个csrf_token
的函数_get_token
def _get_token(self, request):
if settings.CSRF_USE_SESSIONS:
try:
return request.session.get(CSRF_SESSION_KEY)
except AttributeError:
raise ImproperlyConfigured(
'CSRF_USE_SESSIONS is enabled, but request.session is not '
'set. SessionMiddleware must appear before CsrfViewMiddlewar