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时区设置方法与pytz查询时区教程
Nov 27 Python
Python def函数的定义、使用及参数传递实现代码
Aug 10 Python
利用python实现数据分析
Jan 11 Python
Python使用QRCode模块生成二维码实例详解
Jun 14 Python
Python找出最小的K个数实例代码
Jan 04 Python
Python将8位的图片转为24位的图片实现方法
Oct 24 Python
Python实现带参数的用户验证功能装饰器示例
Dec 14 Python
谈一谈基于python的面向对象编程基础
May 21 Python
python中必要的名词解释
Nov 20 Python
使用Python paramiko模块利用多线程实现ssh并发执行操作
Dec 05 Python
flask 框架操作MySQL数据库简单示例
Feb 02 Python
python对数组进行排序,并输出排序后对应的索引值方式
Feb 28 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
《OVERLORD》手游英文版即将上线 手机上也能扮演骨王
2020/04/09 日漫
ECMall支持SSL连接邮件服务器的配置方法详解
2014/05/19 PHP
php中ltrim()、rtrim()与trim()删除字符空格实例
2014/11/25 PHP
[原创]PHP获取数组表示的路径方法分析【数组转字符串】
2017/09/01 PHP
JS判断是否为数字,是否为整数,是否为浮点数的代码
2010/04/24 Javascript
js触发asp.net的Button的Onclick事件应用
2013/02/02 Javascript
JS随机生成不重复数据的实例方法
2013/07/17 Javascript
javascript通过className来获取元素的简单示例代码
2014/01/10 Javascript
使用mouse事件实现简单的鼠标经过特效
2015/01/30 Javascript
jQuery DOM删除节点操作指南
2015/03/03 Javascript
jquery实现表格本地排序的方法
2015/03/11 Javascript
JS Array创建及concat()split()slice()的使用方法
2016/06/03 Javascript
详解Vue中使用v-for语句抛出错误的解决方案
2017/05/04 Javascript
vue watch监听对象及对应值的变化详解
2018/02/24 Javascript
JavaScript如何对图片进行黑白化
2018/04/10 Javascript
vscode配置vue下的es6规范自动格式化详解
2019/03/20 Javascript
VUE实现密码验证与提示功能
2019/10/18 Javascript
javascript二维数组和对象的深拷贝与浅拷贝实例分析
2019/10/26 Javascript
详解小程序如何改变onLoad的执行时机
2019/11/01 Javascript
Vue+Node实现商品列表的分页、排序、筛选,添加购物车功能详解
2019/12/07 Javascript
Vue实现todo应用的示例
2021/02/20 Vue.js
Python 调用DLL操作抄表机
2009/01/12 Python
django 自定义用户user模型的三种方法
2014/11/18 Python
Python利用operator模块实现对象的多级排序详解
2017/05/09 Python
Python随机生成手机号、数字的方法详解
2017/07/21 Python
python2.x实现人民币转大写人民币
2018/06/20 Python
Python+OpenCV实现图像的全景拼接
2020/03/05 Python
python 串行执行和并行执行实例
2020/04/30 Python
BeautifulSoup获取指定class样式的div的实现
2020/12/07 Python
Smashbox官网:美国知名彩妆品牌
2017/01/05 全球购物
汽车检测与维修应届毕业生求职信
2013/10/19 职场文书
青年教师典范事迹材料
2014/01/31 职场文书
女娲补天教学反思
2014/02/05 职场文书
会计求职信
2014/05/29 职场文书
剑指Offer之Java算法习题精讲二叉树专项训练
2022/03/21 Java/Android
HTML静态页面获取url参数和UserAgent的实现
2022/08/05 HTML / CSS