Django的CSRF防攻击原理详解

简介: Django的CSRF防攻击原理详解

CSRF

详述CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。


攻击者通过HTTP请求江数据传送到服务器,从而盗取回话的cookie。盗取回话cookie之后,攻击者不仅可以获取用户的信息,还可以修改该cookie关联的账户信息。

66adb514cf75401b8293e2d5344ca826.png


所以解决csrf攻击的最直接的办法就是生成一个随机的csrftoken值,保存在用户的页面上,每次请求都带着这个值过来完成校验。

那么django中csrf认证怎么玩的呢?

官方文档中说到,检验token时,只比较secret是否和cookie中的secret值一样,而不是比较整个token。

我又有疑问了,同一次登录,form表单中的token每次都会变,而cookie中的token不便,django把那个salt存储在哪里才能保证验证通过呢。直到看到源码。

1、csrf流程

1 在响应的页面中加入{% csrf_token %}标签,那么在进行模板渲染是会生成如下标签

2 并且在响应还有这个 {% csrf_token %}标签的页面时,会添加cookie键值对,如下

csrftoken:lsMQeJgVbIKKxlfz6umgYM8WOWx1Njr77cHzM0L4xtXoApsnhFXXk1OGzwb1dd0G

3 当用户从该页面提交数据时,会携带csrfmiddlewaretoken:ppwN8yg1wVEyXDxtMpVIrc4zV3gHiDKKb9rwGPLaSGRc0HKhXAwpNrKjGDUHIxjj和cookie键值对

4 取出cookie中的csrftoken值和请求数据部分的csrfmiddlewaretoken的值,两者进行比较,这个随机字符串叫做token字符串. django如果在请求数据部分找不到tokne值,会去请求数据中的请求行部分,找一个叫做X-CSRFToken的键值对,如果这个键对应的值和cookie中csrftoken对应的值相同,也能通过认证.

过程:

token字符串的前32位是salt, 后面是加密后的token, 通过salt能解密出唯一的secret字符串。

secret:是settings配置文件中的serect_key:

SECRET_KEY = ‘s!xbzez1zxrevmq7k_89%%-z&#)e7686pyq8pg@_bp_k_2s^ho’

django会验证表单中的token和cookie中token是否能解出同样的secret,secret一样则本次请求合法。

如果不同就403 forbiddensecert_key:

前端页面携带的token值64位

当我们点击添加书籍时,form表单中只要添加了{%csrf_token%},页面就会自动添加个隐藏的input标签,每次请求得到的的value值都不相同

csrftoken的值不变

只要手动改下这个隐藏的input里面的value值,再提交数据就会forbidden。这个值只有是后台给的才能通过鉴权

token字符串的前32位是salt, 后面是加密后的token, 通过salt能解密出唯一的secret。

django会验证表单中的token和cookie中token是否能解出同样的secret,secret一样则本次请求合法。

同样也不难解释,为什么ajax请求时,需要从cookie中拿取token添加到请求头中。


Django默认对修改数据的请求强制要求csrf_token验证

提交表单的请求和响应头都带csrftoken

2、Ajax通过django的csrf_token认证机制的写法

通过form表单登录,放开csrf

那么表单那里就要添加{%csrf_token%},才能提交,不然提交报forbidden

Ajax提交也必须携带csrfmiddlewaretoken 这个键值,否则也不能提交

现在没有添加,提交

报403 forbidden,没通过认证Django回复一个认证错误的页面

三种方式提交都需要在html中添加{%csrf_token%},第一次要在浏览器中存cookie

1.方式一

只需要在html文件中添加{%csrf_token%},然后将csrfmiddlewaretoken的值提交上去就可以

注意:提交数据csrf的键值必须是csrfmiddlewaretoken

$('#btn').click(function () {
    {#发送ajax请求,指定请求方法,请求路径,请求携带的数据(以字典的形式携带)#}
    {# 先获取用户输入内容 #}
    var uname = $('#username').val()
    var pwd = $('#password').val()
    var token = $('[name="csrfmiddlewaretoken"]').val()

    $.ajax({
        type: 'post',
        url: '/login/',
        data: {username: uname, password: pwd, csrfmiddlewaretoken: token}, {# 这里提交数据跟form表单提交数据是一样的,相当于form表单的name属性值 #}
        {# 请求成功后的触发success对应的会调函数,并且将接收到的值给了函数的变量res #}
        {# res接受的是请求成功之后的响应结果,如果ajax判断请求成功和失败,有后台决定 #}
        {# // 后台响应的状态码如果是2xx\3xx等,ajax发现应用状态为2xx\3xx等,ajax就知道请求成功了 #}
        success: function (res) {
            console.log('success', res)
        },
        {# 请求失败的回调函数,/后台响应的状态码为4xx或者5xx表示请求失败或者服务器出问题了,没有正常响应本次请求的内容 #}
        {# ajax接受到响应, 如果发现响应状态码为4xx或者5xx, 那么ajax会自动触发error对应的函数#}
        {# //  并将响应结果传给函数作为参数(error参数 #}

        error: function (error) {
            console.log('error', error)
            {# 错误提示打印到页面上 #}
            {#$('#ajax_error').text('输入的用户名或者密码有误!');#}
            $('#ajax_error').text(error.responseText)

        }

    })
})

登录成功

输入错误登录

说明已经通过验证,前端post请求先过csrf认证,过了才会去找路由

2.方式二:不用js取值,直接在data中取token值

$.ajax({
        type: 'post',  // 请求方法.
        url: '/login/',
        // {{ csrf_token }}拿到是{% csrf_token %}生成的input标签的那个value属性的token值
        data: {xname: uname, pwd: password, csrfmiddlewaretoken: '{{ csrf_token }}'},
        success: function (res) {
            console.log('success', res);

        },
        error: function (error) {
            console.log('error>>>>>', error);
            $('#ajax_error').text(error.responseText);

        }

    })

注意要有引号

浏览器查看,获取的就是token值

3.方式三: 添加请求头键值对,键必须叫做:‘X-CSRFToken’,值是cookie中的token值

需要借助jquery.cookie.js

$.ajax({
        type: 'post',  // 请求方法.
        url: '/login/',

        data: {xname: uname, pwd: password},
        headers:{  // 设置请求头键值对
            'X-CSRFToken':$.cookie('csrftoken'),
        },
        success: function (res) {

            console.log('success', res);

        },
        error: function (error) {
            console.log('error>>>>>', error);
            $('#ajax_error').text(error.responseText);

        }

    })

原生JS代码可以直接获取cookie

3、jquery获取cookie

定义:让网站服务器把少量数据储存到客户端的硬盘或内存,从客户端的硬盘读取数据的一种技术;

下载与引入:jquery.cookie.js基于jquery;先引入jquery,再引入:jquery.cookie.js;下载:http://plugins.jquery.com/cookie/

http://plugins.jquery.com/cookie/

https://www.bootcdn.cn/jquery-cookie/

官网,点download下载

bootcdn第三方加速网,可以复制链接将文件存到本地

引入使用,要先引入jquery

<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/jquery.cookie.js"></script>

1.cookie操作

添加cookie

$.cookie(‘the_cookie’, ‘the_value’);

这里没有指明 cookie有效时间,所创建的cookie有效期默认到用户关闭浏览器为止,所以被称为 “会话cookie(session cookie)”。

创建一个cookie并设置有效时间为 7天

$.cookie(‘the_cookie’, ‘the_value’, { expires: 7 });

   这里指明了cookie有效时间,所创建的cookie被称为“持久 cookie (persistent cookie)”。注意单位是:天;

读取cookie

$.cookie(‘the_cookie’); #the_cookie是键

删除cookie

$.cookie(‘the_cookie’, null); //通过传递null作为cookie的值即可

6.可选参数

$.cookie(‘the_cookie’,‘the_value’,{

expires:7,

path:‘/’,

domain:‘jquery.com’,

secure:true

})

添加请求头键值对,键必须叫做:‘X-CSRFToken’,通过jquery 取token值,值是cookie中的token值

这红方式能使用的前提是浏览器中本来要有csrftoken这个token,不然jquery获取不到token,依然提交不了

可以正常登录

可以看到浏览器请求头中包含了X-CSRFToken键值对

总结,如上,就是全部的CSRF的实现运用原理


相关文章
|
12天前
|
安全 前端开发 JavaScript
什么是 CSRF 攻击?如何启用 CSRF 保护来抵御该攻击?
什么是 CSRF 攻击?如何启用 CSRF 保护来抵御该攻击?
39 5
|
29天前
|
存储 Web App开发 安全
如何防范 CSRF 攻击
CSRF(跨站请求伪造)攻击是一种常见的安全威胁。防范措施包括:使用Anti-CSRF Token、检查HTTP Referer、限制Cookie作用域、采用双重提交Cookie机制等,确保请求的合法性与安全性。
|
29天前
|
网络安全 数据安全/隐私保护
什么是 CSRF 攻击
CSRF(跨站请求伪造)攻击是指攻击者诱导用户点击恶意链接或提交表单,利用用户已登录的身份在目标网站上执行非授权操作,如转账、修改密码等。这种攻击通常通过嵌入恶意代码或链接实现。
|
1月前
|
安全 前端开发 Java
Web安全进阶:XSS与CSRF攻击防御策略深度解析
【10月更文挑战第26天】Web安全是现代软件开发的重要领域,本文深入探讨了XSS和CSRF两种常见攻击的原理及防御策略。针对XSS,介绍了输入验证与转义、使用CSP、WAF、HTTP-only Cookie和代码审查等方法。对于CSRF,提出了启用CSRF保护、设置CSRF Token、使用HTTPS、二次验证和用户教育等措施。通过这些策略,开发者可以构建更安全的Web应用。
83 4
|
1月前
|
安全 Go PHP
Web安全进阶:XSS与CSRF攻击防御策略深度解析
【10月更文挑战第27天】本文深入解析了Web安全中的XSS和CSRF攻击防御策略。针对XSS,介绍了输入验证与净化、内容安全策略(CSP)和HTTP头部安全配置;针对CSRF,提出了使用CSRF令牌、验证HTTP请求头、限制同源策略和双重提交Cookie等方法,帮助开发者有效保护网站和用户数据安全。
66 2
|
1月前
|
存储 安全 Go
Web安全基础:防范XSS与CSRF攻击的方法
【10月更文挑战第25天】Web安全是互联网应用开发中的重要环节。本文通过具体案例分析了跨站脚本攻击(XSS)和跨站请求伪造(CSRF)的原理及防范方法,包括服务器端数据过滤、使用Content Security Policy (CSP)、添加CSRF令牌等措施,帮助开发者构建更安全的Web应用。
84 3
|
1月前
|
SQL 存储 安全
什么是XSS攻击?什么是SQL注入攻击?什么是CSRF攻击?
理解并防范XSS、SQL注入和CSRF攻击是Web应用安全的基础。通过采用严格的输入验证、使用安全编码实践以及实现适当的身份验证和授权机制,可以有效防止这些常见的Web攻击,保障应用程序和用户的数据安全。
37 0
|
2月前
|
中间件 应用服务中间件 nginx
Nginx+uWSGI+Django原理
Nginx+uWSGI+Django原理
|
3月前
|
Python
django 路由分发:原理
django 路由分发:原理
|
5月前
|
SQL 安全 数据库
Python Web开发者必学:SQL注入、XSS、CSRF攻击与防御实战演练!
【7月更文挑战第26天】在 Python Web 开发中, 安全性至关重要。本文聚焦 SQL 注入、XSS 和 CSRF 这三大安全威胁,提供实战防御策略。SQL 注入可通过参数化查询和 ORM 框架来防范;XSS 则需 HTML 转义用户输入与实施 CSP;CSRF 防御依赖 CSRF 令牌和双重提交 Cookie。掌握这些技巧,能有效加固 Web 应用的安全防线。安全是持续的过程,需贯穿开发始终。
95 1
Python Web开发者必学:SQL注入、XSS、CSRF攻击与防御实战演练!