Django CSRF

CSRF攻击过程

攻击说明:

1.用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登陆网站A;

2.在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登陆网站A成功,可以正常发送请求到网站A;

3.用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B;

4.网站B收到用户请求后,返回一些攻击性代码,并发出一个请求,要求访问第三方站点A;

5.浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。

CSRF的攻击之所以会成功是因为服务器端身份验证机制可以通过Cookie保证一个请求是来自于某个用户的浏览器,>单无法保证该请求是用户允许的。因此,预防CSRF攻击简单可行的方法就是在客户端网页上添加随机数,在服务器>端进行随机数验证,以确保该请求是用户允许的。Django也是通过这个方法来预防CSRF攻击的。

Django防御CSRF攻击

原理

在客户端页面上天机csrftoken,服务器端进行验证。服务器端验证的工作通过"django.middleware.csrf.CsrfViewMiddleware"这个中间件来完成。在Django中防御csrf攻击的方式有两种:

  • 在表单中附加csrftoken;
  • 通过request请求中添加x-csrftoken请求头;

注意:Django默认对所有的POST请求都进行csrftoken验证,若验证失败则返回403错误。Django中设置防跨站请求伪造功能分为全局和局部。

全局:中间件 django.middleware.csrf.CsrfViewMiddleware

局部:from django.views.decorators.csrf import csrf_protect, csrf_exempt

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

当用post提交数据的时候,django会去检查是否有一个csrf的随机字符串,如果没有就会报错,错误如下:



在Django内部支持生成这个随机字符串。

通过form提交

在form表单里面需要添加{% csrf_token %},这样当查看页面源码的时候,可以看到form中有一个input是隐藏的:

原理总结:

当用户访问login页面的时候,会生成已给csrf的随机字符串,并且cookie中野村放了这个随机字符串,当用户再次提交数据的时候会带着这个随机字符串提交,如果没有这个随机字符串则无法提交成功。cookie中存放的csrftoken如下图所示:

通过ajax提交

因为cookie中同样存在csrftoken,所以可以在JavaScript中通过$.cookie("csrftoken")获取。如果通过ajax进行提交数据,这里提交的csrftoken是通过请求头中存放,需要提交一个字典型的数据,即这时候需要一个key。在views中的login函数中:from django.conf import settings,然后打印print(settings.CSRF_HEADER_NAME),这里需要注意一个问题,这里导入的settings并不是我们在项目下看到的settings.py文件,这里是一个全局的settings配置,而当我们在项目目录下的settings.py中配置的时候,我们添加的配置则会覆盖全局settings中的配置。print(settings.CSRF_HEADER_NAME)打印的内容为:HTTP_X_CSRFTOKEN,这里的HTTP_X_CSRFTOEKN是Django在X_CSRF的前面添加了HTTP_,所以实际传递的就是X_CSRFTOKEN,而在前端页面的ajax传递的时候由于不能使用下划线,所以传递的是X_CSRFTOKEN。下面是在前端ajax中写的具体内容:

$("#btn1").click(function () {
$.ajax({
url:"/login/",
type:"POST",
data:{"usr":"root","pwd":"123"},
headers:{ "X-CSRFtoken":$.cookie("csrftoken")},
success:function (arg) { };
});
});

但是如果页面中有多个ajax请求的话,就在每个ajax中添加headers信息,所以可以通过下面方式在所有的ajax中都添加:

 $.ajaxSetup({
beforeSend:function (xhr,settings) {
xhr.setRequestHeader("X-CSRFtoken",$.cookie("csrftoken"))
}
});

这样就会在提交ajax之前执行这个方法,从而在所有的ajax里都加上这个csrftoken,这里的xhr是XMLHttpRequest的简写,ajax调用的就是这个方法。如果想要实现在当get方式的时候不需要提交csrftoken,当post的时候需要,实现这种效果的代码如下:

function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
};
};
});

这样就实现了当GET|HEAD|OPTIONS|TRACE这些方式请求的时候不需要提交csrftoken。

总结:

1、csrf在ajax提交的时候通过请求头传递给后台的;

2、csrf在前端的key为:X-CSRFToken,到后端的时候Django会自动添加HTTP_,并且最后为HTTP_X_CSRFTOKEN;

3、csrf在form中提交的时候需要在前端form中添加{% csrftoken %};

Django 2.0 学习(22):Django CSRF的更多相关文章

  1. Django 2.0 学习(07):Django 视图(进阶-续)

    接Django 2.0 学习(06):Django 视图(进阶),我们将聚焦在使用简单的表单进行处理和精简代码. 编写简单表单 我们将用下面的代码,来替换之前的detail模板("polls ...

  2. Django 2.0 学习(04):Django数据库

    数据库设置/配置 打开mysite/settings.py,我们会发现Django是用的是默认的数据库SQLite,如下图所示: Django也是支持其它数据库的,比如PostgreSQL.MySQL ...

  3. Django 2.0 学习(12):Django 模板语法

    Django 模板语法 一.模板 只要是在html里面有模板语法就不是html文件了,这样的文件就叫做模板. 二.模板语法 模板语法变量:{{ }} 在Django模板中遍历复杂数据结构的关键是句点字 ...

  4. Django 2.0 学习

    Django django是基于MTV结构的WEB框架 Model 数据库操作 Template 模版文件 View 业务处理 在Python中安装django 2.0 1 直接安装 pip inst ...

  5. Django 2.0 学习(19):Django 分页器

    Django 分页器 要使用Django实现分页功能,必须从Django中导入Paginator模块(painator - 分页器) views.py from django.shortcuts im ...

  6. Django 2.0 学习(08):Django 自动化测试

    编写我们的第一个测试 确定bug 幸运的是,在polls应用中存在一个小小的bug急需修复:无论Question的发布日期是最近(最后)的日期,还是将来很多天的日期,Question.was_publ ...

  7. Django 2.0 学习(06):Django 视图(进阶)

    概述 Django中的特方法,该方法代表了Django的Web页面,并且视图具有特定的模板.以博客应用为例进行说明,在博客应用中应该包含下面的视图: 博客主页:显示最近的一些记录: 详细页面:单个详细 ...

  8. Django 2.0 学习(03):Django视图和URL(下)

    接上篇博文,继续分析Django基本流程. 编写第一个(view)视图函数 1.打开文件polls/views.py,输入下面的Python代码: from django.http import Ht ...

  9. Django 2.0 学习(01):Django初识与安装

    Django(Python Web框架) Django是一个开放源代码的Web框架,用Python写的.采用了MTV的框架模式,即模型M,模板T和视图V.它最初被开发是用来管理以新闻内容为主的网站,即 ...

随机推荐

  1. Zabbix实战-简易教程--WEB类--Nginx

    一.开启Nginx status状态 1.在默认主机里面加上location添加ngx_status 如下操作: server { listen 127.0.0.1:8080; server_name ...

  2. Python无参装饰器

    需求:想要在test_func函数前后执行一些代码   1.第一步(定义函数,将调用原函数,使用新函数替换) def test_func(): return 'test_func' def test_ ...

  3. Java将List<T>集合组装成树(Tree)树结构组装

    把列表转换为树结构 /** * 把列表转换为树结构 * * @param originalList 原始list数据 * @param keyName 作为唯一标示的字段名称 * @return 组装 ...

  4. Android Studio —— java.lang.VerifyError: Verifier rejected class 问题解决

    用as开发过程中遇见问题app闪退  log如下图: 解决: File—Settings: 点击Apply—OK重新运行即可

  5. Android Service(下)

    阅读本文需要先阅读Android Service(上) 一 为什么需要bindService() 绑定服务就是为了和服务进行通讯 可以调用服务里面的方法 二 bindService()调用服务里面方法 ...

  6. Keycloak服务器安装和配置

    安装地址:https://www.keycloak.org/archive/downloads-4.4.0.html 参考文档:https://www.keycloak.org/docs/latest ...

  7. ovs源码阅读--netlink使用

    netlink netlink socket是一种用于用户态进程和内核态进程之间的通信机制.它通过为内核模块提供一组特殊的API,并为用户程序提供了一组标准的socket接口的方式,实现了全双工的通讯 ...

  8. 部署Maven项目到tomcat报错:java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener【转】

    部署Maven项目到tomcat报错:java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderLi ...

  9. 王者荣耀交流协会final发布-第一次scrum立会

    1.例会照片 成员王超,高远博,冉华,王磊,王玉玲,任思佳,袁玥全部到齐 master:袁玥 2.时间跨度 2017年12月1日 17:00 — 17:31,总计31分钟 3.地点 一食堂二楼沙发座椅 ...

  10. Java第二次实验20135204

    一.实验过程: 1.先创建一个学号命名的文档: 2.一个百分制成绩转化为等级: 3.新建一个包,另一个测试: 4.打开UML,建模软件umbrello进行建模: 相关程序: 5.我的保存: 二.遇到的 ...