Django 安全之跨站点请求伪造(CSRF)保护

简介: Django 安全之跨站点请求伪造(CSRF)保护

Django 安全之跨站点请求伪造(CSRF)保护



测试环境

Win7

Django 1.11

 

 

跨站点请求伪造(CSRF)保护

中间件配置

默认的CSRF中间件在MIDDLEWARE中定义并处于激活状态。如果需要变更默认配置,修改settings.py中的MIDDLEWARE配置即可,如下,假设要开启CSRF,确保列表包含  'django.middleware.csrf.CsrfViewMiddleware',并且其位置位于其它会对CSRF攻击进行处理的中间件之前,假设要禁用CSRF中间件,去掉列表中的'django.middleware.csrf.CsrfViewMiddleware',或者采用注释方式,把 'django.middleware.csrf.CsrfViewMiddleware' 注释掉。注意:更改配置后需要重启web服务器。

 

MIDDLEWARE = [

   ……,

'django.middleware.csrf.CsrfViewMiddleware',

……

]

 

如果CSRF中间件被禁用(不推荐),又想对特定视图启用中间件保护,则可以针对特定视图使用csrf_protect()修饰器,如下:

from django.views.decorators.csrf import csrf_protect

 

@csrf_protect

def specific_view(request):

   do something

 

参考链接:https://docs.djangoproject.com/en/2.1/ref/csrf/#django.views.decorators.csrf.csrf_protect

 

 

相反的,如果中间件已经开启,但是又不想针对特定视图使用中间件保护,则可以针对特定视图使用csrf_exempt() 修饰器

from django.views.decorators.csrf import csrf_exempt

 

 

@csrf_exempt

def specific_view(request):

do something

 

参考链接:https://docs.djangoproject.com/en/2.1/ref/csrf/#utilities

 

 

html模板配置

开启CSRF中间件的情况下,要在html模板中为使用post方法的form表单新增 csrf_token tag,如下:

 

<form method="post">

{% csrf_token %}

<input ...>... </input>

...

</form>

 

注意:如果被渲染的view视图未使用csrf_token模板标签,Django可能不会设置CSRF token cookie。这种情况下,假如有必要,可以使用Django提供的 @ensure_csrf_cookie()装饰器强制view视图发送CSRF cookie。

 

from django.views.decorators.csrf import ensure_csrf_cookie

 

@ensure_csrf_cookie()

def specific_view(request):

do something

 

view视图函数

对应的视图函数中,确保使用了RequestContext来渲染response,以便{%csrf_token %}可以正常运行。因为 render()函数使用了RequestContext,所以一般的view中,使用render()也是可以的。

 

 

前端js脚本

注意:如果已开启CSRF 的情况下,需要给请求添加X_CSRFTOKEN 请求头,否则会报403错误

/**

* 验证不需要CSRF保护的HTTP方法名(GET|HEAD|OPTIONS|TRACE

*/

function csrfSafeMethod(method) {

return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));

}

 

/**

* 获取cookie项的值

* key:cookie名称

*/

function getCookie(key) {

 

var cookies = document.cookie.split(';'); // 获取每个cookie项(不含会话id)

var value = undefined;

for (var i in cookies) {

var kv = cookies[i].split('='); // 每个cookie项的名称和cookie的值

var temp_key = kv[0].replace(' ', ''); // 获取的cookie项有多个值,第二个开始,键 的值 的左侧会加个空格

if (key == temp_key) {

var value = kv[1];

break;

       }

   }

return value;

}

 

 

/**

* Created by shouke on 2018/11/1.

*/

 

//全局变量设置

var loginURL = '/platform/api/v1/login'; // 注册api地址

var loginFormID = 'login-form';           // 登录表单ID

var registerRightNowID = 'registerRightNow' // 立即注册链接ID

 

/**

* 初始化

*/

$(document).ready(function() {

// 设置顶部导航

setTopNav();

 

var resources = $.session.get('resources');

if (resources) {

resources = JSON.parse(resources).resources;

// 设置立即注册url

$("#" + registerRightNowID).attr("href", resources.register_url.url);

} else {

alert('获取资源失败,导致设置立即注册连接失败');

}

 

// 为登录表单绑定提交事件

$('#' + loginFormID).submit(function() {

/**

        * 提交登录信息

        */

var dataArray = $('#' + loginFormID).serializeArray();

 

var data = {}

$.each(dataArray, function () {

data[this.name] = this.value;

     });

 

var csrfToken = getCookie('csrftoken');

if (csrfToken == undefined) {

alert('获取Cookie失败');

return false;

     }

 

$.ajax({

type: "POST",

url: loginURL,

async: false,

data: data,

beforeSend: function (xhr, settings) {

if (!csrfSafeMethod(settings.type) && !this.crossDomain) {

                   xhr.setRequestHeader("X-CSRFTOKEN", csrfToken);

            }

        },

success: function (result) {

if (result.success == 'true') {

alert(result.msg);

$.session.remove('resources');                // 清空登录前获取的资源,以便重新获取资源

                // 重定向返回登录前的页面

window.location.href = result.next;

           } else {

alert(result.msg + "," + result.reason);

           }

      },

error: function(XmlHttpRequest, textStatus, errorThrown) {

alert('登录请求失败' + XmlHttpRequest.responseText);

      }

   });

return false;

});

});

 

注意:这里最后面添加的return false; 主要是用于 避免跳转到django后台的返回结果数据页

 

 

参考链接

https://docs.djangoproject.com/en/2.1/ref/csrf/#using-csrf

https://docs.djangoproject.com/en/2.1/topics/security/#cross-site-request-forgery-csrf-protection

 

 

目录
相关文章
|
5月前
|
SQL 存储 安全
Web安全-CSRF跨站请求伪造
Web安全-CSRF跨站请求伪造
135 4
|
7月前
|
SQL 安全 数据库
从入门到精通:Python Web安全守护指南,SQL注入、XSS、CSRF全防御!
【7月更文挑战第25天】在Python Web开发中确保应用安全至关重要。以下是针对SQL注入、XSS与CSRF攻击的防护策略及示例代码
93 6
|
7月前
|
SQL 安全 数据库
|
7月前
|
SQL 存储 安全
Python Web安全大挑战:面对SQL注入、XSS、CSRF,你准备好了吗?
【7月更文挑战第25天】在Python Web应用开发中,安全至关重要,需防范如SQL注入、XSS与CSRF等攻击。**SQL注入**风险可通过避免直接拼接用户输入至SQL语句,改用参数化查询来缓解。**XSS**则需对用户输入的内容进行HTML转义处理,防止恶意脚本执行。对于**CSRF**,实现包括生成并验证CSRF令牌在内的防护机制是关键。综合运用这些防御策略能显著增强应用的安全性,但需持续学习以对抗不断变化的威胁。
95 5
|
6月前
|
JSON 前端开发 数据安全/隐私保护
Django入门到放弃之CSRF_TOKEN
Django入门到放弃之CSRF_TOKEN
|
7月前
|
SQL 安全 数据库
深度揭秘:Python Web安全攻防战,SQL注入、XSS、CSRF一网打尽!
【7月更文挑战第27天】在 Web 开发中,Python 面临着如 SQL 注入、XSS 和 CSRF 等安全威胁。
85 0
|
7月前
|
SQL 安全 前端开发
Web安全新纪元:Python如何筑起SQL注入、XSS、CSRF的铜墙铁壁?
【7月更文挑战第26天】在Web开发中,安全性至关重要。Python提供强大工具来抵御SQL注入、XSS和CSRF等威胁。使用ORM如Django和SQLAlchemy可防SQL注入; Django等框架自动转义输出防XSS; CSRF通过自动及手动验证令牌来阻止。开发者须持续学习最新安全实践以保护用户数据。迈向Web安全新纪元,Python助你一臂之力。
54 1
|
6月前
|
存储 前端开发 Serverless
中后台前端开发问题之Django项目中接收和处理用户的抽奖请求如何解决
中后台前端开发问题之Django项目中接收和处理用户的抽奖请求如何解决
30 0