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

 

 

目录
打赏
0
0
0
0
18
分享
相关文章
Django表单验证和过滤机制在应对复杂安全场景时可能存在哪些漏洞?
Django表单验证和过滤机制在应对复杂安全场景时可能存在哪些漏洞?
142 71
Django框架的表单验证和过滤机制是否可以应对复杂的安全场景?
综上所述,Django 框架的表单验证和过滤机制在一定程度上可以应对复杂的安全场景,但需要综合运用多种手段来进一步提升安全性,以适应不断变化的安全挑战。
125 52
|
7月前
|
Web安全-CSRF跨站请求伪造
Web安全-CSRF跨站请求伪造
161 4
【惊险揭秘】Django高手的十大安全秘籍:如何从零构建坚不可摧的Web堡垒?
【8月更文挑战第31天】《Django安全性指南:构建安全Web应用的十大关键步骤》介绍了在使用Django框架开发Web应用时,如何通过十个关键步骤提升应用安全性。从使用HTTPS、设置CSRF保护到限制密码复杂度、防止SQL注入,文章详细阐述了每一步的具体实施方法及示例代码,帮助开发者构建更加安全可靠的Web应用。
90 0
深度揭秘:Python Web安全攻防战,SQL注入、XSS、CSRF一网打尽!
【7月更文挑战第27天】在 Web 开发中,Python 面临着如 SQL 注入、XSS 和 CSRF 等安全威胁。
95 0
Web安全新纪元:Python如何筑起SQL注入、XSS、CSRF的铜墙铁壁?
【7月更文挑战第26天】在Web开发中,安全性至关重要。Python提供强大工具来抵御SQL注入、XSS和CSRF等威胁。使用ORM如Django和SQLAlchemy可防SQL注入; Django等框架自动转义输出防XSS; CSRF通过自动及手动验证令牌来阻止。开发者须持续学习最新安全实践以保护用户数据。迈向Web安全新纪元,Python助你一臂之力。
62 1
中后台前端开发问题之Django项目中接收和处理用户的抽奖请求如何解决
中后台前端开发问题之Django项目中接收和处理用户的抽奖请求如何解决
35 0
告别Web安全小白!Python实战指南:抵御SQL注入、XSS、CSRF的秘密武器!
【7月更文挑战第27天】在 Web 开发中,安全漏洞如同暗礁,其中 SQL 注入、XSS 和 CSRF 尤为棘手。本文通过实战案例展示如何使用 Python 抵御这些威胁。
84 0