Django CSRF跨站请求伪造防护过程解析


Posted in Python onJuly 31, 2019

前言

CSRF全称Cross-site request forgery(跨站请求伪造),是一种网络的攻击方式,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF。

攻击原理

1、用户访问正常的网站A,浏览器就会保存网站A的cookies。

2、用户在访问恶意网站B, 网站B上有某个隐藏的链接会自动请求网站A的链接地址,例如表单提交,传指定的参数。

3、恶意网站B的自动化请求,执行就是在用户A的同一个浏览器上,因此在访问网站A的时候,浏览器会自动带上网站A的cookies。

4、所以网站A在接收到请求之后,可判断当前用户登录状态,所以根据用户的权限做具体的操作逻辑。

防范措施

1、在指定表单或者请求头的里面添加一个随机值做为参数。

2、在响应的cookie里面也设置该随机值。

3、用户正常提交表单的时候会默认带上表单中的随机值,浏览器会自动带上cookie里面的随机值,那么服务器下次接受到请求之后就可以取出两个值进行校验。

4、对于网站B来说网站B在提交表单的时候不知道该随机值是什么,所以就形成不了攻击。

Django中CSRF中间件

django在创建项目的时候,默认就会有添加中间进行CSRF的保护,在MIDDLEWARE可以看到加载了 django.middleware.csrf.CsrfViewMiddleware 的中间件,这里是全局设置,也可以局部设置。

全局保护:直接启用中间件就可以了。

局部保护: from django.views.decorators.csrf import csrf_exempt,csrf_protect ,使用装饰器进行验证。

csrf_protect :为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件;

csrf_exempt :取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。

验证

在POST请求提交数据的时候,django会去检查是否有一个csrf的随机字符串,如果没有就会返回403没有权限访问。

表单验证

在form表单里面需要添加{%csrf_token%},Django会自动渲染隐藏的input输入框:

<input type="hidden" name="csrfmiddlewaretoken" value="2Sb0DQwDVgOQ8i3n1BaG1MUPLEYr6ZGaCLYa14maOQM0Ami5ddQOR6hfXuD2mrmA">

在表单提交的时候,中间件会验证csrfmiddlewaretoken。

通过ajax提交

通过cookies获取到csrftoken,

function getCookie(name) {
  var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
  return r ? r[1] : undefined;
}
$.ajax({
  url:"/api/v1.0/orders",
  type:"POST",
  data: JSON.stringify(data),
  contentType: "application/json",
  dataType: "json",
  headers:{
    "X-CSRFtoken":getCookie("csrf_token"),
  },

局部禁用或者启用

1、如果是函数视图,可以直接在函数加上装饰器即可:

from django.views.decorators.csrf import csrf_exempt,csrf_protect
@csrf_exempt
def login(request):
  if request.method == 'GET':
    return render(request,'login.html')
  else:
    return HttpResponse('ok')

2、如果是类视图,需要使用方法装饰器进行封装

from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt,csrf_protect
from django.views.generic import TemplateView

@method_decorator(csrf_exempt)
class LoginView(TemplateView):
  template_name = 'login.html'
  def post():
    return HttpResponse('ok')

3、直接装饰as_view()方式,在URLconf里面设置。

from django.views.decorators.csrf import csrf_exempt,csrf_protect
urlpatterns = [
  path('login/', csrf_exempt(LoginView.as_view()),name="login"),
]

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python批量查询域名是否被注册过
Jun 21 Python
flask中使用蓝图将路由分开写在不同文件实例解析
Jan 19 Python
在python里从协程返回一个值的示例
Feb 19 Python
详解Python 函数如何重载?
Apr 23 Python
Python通用函数实现数组计算的方法
Jun 13 Python
解决yum对python依赖版本问题
Jul 05 Python
利用Python复制文件的9种方法总结
Sep 02 Python
Python制作词云图代码实例
Sep 09 Python
python统计文章中单词出现次数实例
Feb 27 Python
python实现计算图形面积
Feb 22 Python
python 机器学习的标准化、归一化、正则化、离散化和白化
Apr 16 Python
python自动化操作之动态验证码、滑动验证码的降噪和识别
Aug 30 Python
在VS2017中用C#调用python脚本的实现
Jul 31 #Python
使用pip安装python库的多种方式
Jul 31 #Python
python实现几种归一化方法(Normalization Method)
Jul 31 #Python
python Django编写接口并用Jmeter测试的方法
Jul 31 #Python
python实现windows倒计时锁屏功能
Jul 30 #Python
python创建属于自己的单词词库 便于背单词
Jul 30 #Python
python中append实例用法总结
Jul 30 #Python
You might like
PHP中HTML标签过滤技巧
2014/01/07 PHP
php rmdir使用递归函数删除非空目录实例详解
2016/10/20 PHP
laravel unique验证、确认密码confirmed验证以及密码修改验证的方法
2019/10/16 PHP
在JS中最常看到切最容易迷惑的语法(转)
2010/10/29 Javascript
简短几句jquery代码的实现一个图片向上滚动切换
2011/09/02 Javascript
JavaScript高级程序设计 事件学习笔记
2011/09/10 Javascript
使用JavaScript进行进制转换将字符串转换为十进制
2014/09/21 Javascript
Javascript中使用parseInt函数需要注意的问题
2015/04/02 Javascript
jquery 全选、全不选、反选效果的实现代码【推荐】
2016/05/05 Javascript
原生JavaScript编写canvas版的连连看游戏
2016/05/29 Javascript
浅谈Vue 初始化性能优化
2017/08/31 Javascript
vue实现文件上传功能
2018/08/13 Javascript
小程序登录态管理的方法示例
2018/11/13 Javascript
了解前端理论:rscss和rsjs
2019/05/23 Javascript
vue动态加载SVG文件并修改节点数据的操作代码
2020/08/17 Javascript
在vue项目中引用Antv G2,以饼图为例讲解
2020/10/28 Javascript
[02:33]DOTA2英雄基础教程 司夜刺客
2013/12/04 DOTA
python的Template使用指南
2014/09/11 Python
学习python之编写简单简单连接数据库并执行查询操作
2016/02/27 Python
Python通过matplotlib画双层饼图及环形图简单示例
2017/12/15 Python
Python opencv实现人眼/人脸识别以及实时打码处理
2019/04/29 Python
Django ModelForm组件使用方法详解
2019/07/23 Python
python ffmpeg任意提取视频帧的方法
2020/02/21 Python
Python range与enumerate函数区别解析
2020/02/28 Python
django 多数据库及分库实现方式
2020/04/01 Python
Scrapy爬虫文件批量运行的实现
2020/09/30 Python
印尼在线精品店:Berrybenka.com
2016/10/22 全球购物
巴西女装购物网站:Eclectic
2018/04/24 全球购物
Charles & Keith欧盟:新加坡时尚品牌
2019/08/01 全球购物
消防器材管理制度
2014/01/28 职场文书
小学生考试获奖感言
2014/01/30 职场文书
2015年九一八事变纪念日演讲稿
2015/03/19 职场文书
干货:如何写好工作计划!
2019/05/17 职场文书
JavaScript实现班级抽签小程序
2021/05/19 Javascript
VUE递归树形实现多级列表
2022/07/15 Vue.js
nginx sticky实现基于cookie负载均衡示例详解
2022/12/24 Servers