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的实现运用原理


相关文章
|
3月前
|
缓存 安全 JavaScript
前端安全:Vue应用中防范XSS和CSRF攻击
【4月更文挑战第23天】本文探讨了在Vue应用中防范XSS和CSRF攻击的重要性。XSS攻击通过注入恶意脚本威胁用户数据,而CSRF则利用用户身份发起非授权请求。防范措施包括:对输入内容转义、使用CSP、选择安全的库;采用Anti-CSRF令牌、同源策略和POST请求对抗CSRF;并实施代码审查、更新依赖及教育团队成员。通过这些实践,可提升Vue应用的安全性,抵御潜在攻击。
578 0
|
24天前
|
SQL 安全 数据库
Python Web开发者必学:SQL注入、XSS、CSRF攻击与防御实战演练!
【7月更文挑战第26天】在 Python Web 开发中, 安全性至关重要。本文聚焦 SQL 注入、XSS 和 CSRF 这三大安全威胁,提供实战防御策略。SQL 注入可通过参数化查询和 ORM 框架来防范;XSS 则需 HTML 转义用户输入与实施 CSP;CSRF 防御依赖 CSRF 令牌和双重提交 Cookie。掌握这些技巧,能有效加固 Web 应用的安全防线。安全是持续的过程,需贯穿开发始终。
48 1
Python Web开发者必学:SQL注入、XSS、CSRF攻击与防御实战演练!
|
10天前
|
Web App开发 存储 安全
就一次!带你彻底搞懂CSRF攻击与防御
与XSS攻击相比,利用CSRF漏洞发动攻击会比较困难,这也是在网络上看起来CSRF的人气小于XSS的原因之一。下面我们来利用CSRF漏洞发起攻击,并针对攻击进行防御,彻底弄懂CSRF,话不多说,我们直接开冲。
|
23天前
|
运维 安全 Java
什么是 CSRF?如何防止 CSRF 攻击?
CSRF 攻击是一种常见且危险的 Web 安全漏洞,攻击者可以通过伪造用户请求,执行恶意操作,作为程序员,为了防御 CSRF 攻击,常见的策略包括使用 CSRF Token、检查 Referer 或 Origin 头、设置 SameSite Cookie 属性以及双重提交 Cookie。 因为程序员对于 CSRF 攻击可以做的事情还是很有限,所以,承担主要责任的是安全部门或者运维部门,但是作为程序员,我们需要具备这些安全意识,在安全等级比较高的需求中也需要把这些安全因素考虑在内。
|
2月前
|
前端开发 安全 JavaScript
XSS和CSRF攻击概览
【6月更文挑战第27天】**XSS和CSRF攻击概览** - XSS:利用未验证用户输入的Web应用,注入恶意脚本到浏览器,盗取信息或控制用户账户。防御措施包括输入验证、内容编码、HttpOnly Cookie和CSP。 - CSRF:攻击者诱使用户执行非授权操作,利用现有会话。防御涉及CSRF Tokens、双重验证、Referer检查和SameSite Cookie属性。 应用这些策略可提升Web安全,定期审计和测试同样重要。
37 3
|
1月前
|
前端开发 安全 JavaScript
CSRF 攻击是什么?如何防范?
CSRF 攻击是什么?如何防范?
28 0
|
2月前
|
前端开发 JavaScript 安全
跨域问题与Django解决方案:深入解析跨域原理、请求处理与CSRF防护
跨域问题与Django解决方案:深入解析跨域原理、请求处理与CSRF防护
|
3月前
|
安全 前端开发 JavaScript
在Python Web开发过程中:Web框架相关,如何在Web应用中防止CSRF攻击?
在Python Web开发中防范CSRF攻击的关键措施包括:验证HTTP Referer字段、使用CSRF token、自定义HTTP头验证、利用Web框架的防护机制(如Django的`{% csrf_token %}`)、Ajax请求时添加token、设置安全会话cookie及教育用户提高安全意识。定期进行安全审计和测试以应对新威胁。组合运用这些方法能有效提升应用安全性。
38 0
|
3月前
|
存储 中间件 数据安全/隐私保护
Django的CSRF保护机制:保障用户数据安全
【4月更文挑战第15天】Django是一款具有内置CSRF保护的Python Web框架,通过CSRF中间件防止攻击者伪造用户请求。其机制包括:生成并自动添加到表单的CSRF令牌,服务器端的令牌验证以及每个用户会话的唯一令牌存储。为了增强防护,开发者应使用HTTPS,自定义令牌名称,限制跨域请求,并谨慎处理第三方库。Django的CSRF保护与最佳实践结合,能有效保障用户数据安全。
|
11天前
|
机器学习/深度学习 数据采集 数据可视化
基于爬虫和机器学习的招聘数据分析与可视化系统,python django框架,前端bootstrap,机器学习有八种带有可视化大屏和后台
本文介绍了一个基于Python Django框架和Bootstrap前端技术,集成了机器学习算法和数据可视化的招聘数据分析与可视化系统,该系统通过爬虫技术获取职位信息,并使用多种机器学习模型进行薪资预测、职位匹配和趋势分析,提供了一个直观的可视化大屏和后台管理系统,以优化招聘策略并提升决策质量。