Django CRSF攻击及处理
一、CRSF简介
CSRF攻击的全称是跨站请求伪造( cross site request forgery),是一种对网站的恶意利用,
尽管听起来跟XSS跨站脚本攻击有点相似,但事实上CSRF与XSS差别很大,XSS利用的是站点内的信任用户,而CSRF则是通过伪装来自受信任用户的请求来利用受信任的网站。
你可以这么理解CSRF攻击:攻击者盗用了你的身份,以你的名义向第三方网站发送恶意请求。
CRSF能做的事情包括利用你的身份发邮件、发短信、盗取你的账号、进行交易转账、购买商品,虚拟货币转账等。
造成的问题包括:个人隐私泄露以及财产安全
二、CRSF攻击原理
从上图可以看出,要完成一次CSRF攻击,受害者必须依次完成两个步骤: 1.登录受信任网站A,并在本地生成Cookie。 2.在不登出A的情况下,访问危险网站B。
看到这里,你也许会说:“如果我不满足以上两个条件中的一个,我就不会受到CSRF的攻击”。是的,确实如此,但你不能保证以下情况不会发生: 1.你不能保证你登录了一个网站后,不再打开一个tab页面并访问另外的网站。 2.你不能保证你关闭浏览器了后,你本地的Cookie立刻过期,你上次的会话已经结束。
(事实上,关闭浏览器不能结束一个会话,但大多数人都会错误的认为关闭浏览器就等于退出登录/结束会话了......) 3.上图中所谓的攻击网站,可能是一个存在其他漏洞的可信任的经常被人访问的网站。
三、CSRF的防御
可以从服务端和客户端两方面着手,防御效果是从服务端着手效果比较好,现在一般的CSRF防御也都在服务端进行。
#1、尽量使用POST,限制GET GET接口太容易被拿来做CSRF攻击,看上面示例就知道,只要构造一个img标签,而img标签又是不能过滤的数据。接口最好限制为POST使用,GET则无效,降低攻击风险。 当然POST并不是万无一失,攻击者只要构造一个form就可以,但需要在第三方页面做,这样就增加暴露的可能性。 #2、将cookie设置为HttpOnly CRSF攻击很大程度上是利用了浏览器的cookie,为了防止站内的XSS漏洞盗取cookie,需要在cookie中设置“HttpOnly”属性, 这样通过程序(如JavaScript脚本、Applet等)就无法读取到cookie信息,避免了攻击者伪造cookie的情况出现。 在Java的Servlet的API中设置cookie为HttpOnly的代码如下: response.setHeader( "Set-Cookie", "cookiename=cookievalue;HttpOnly"); #3、增加token CSRF攻击之所以能够成功,是因为攻击者可以伪造用户的请求,该请求中所有的用户验证信息都存在于cookie中, 因此攻击者可以在不知道用户验证信息的情况下直接利用用户的cookie来通过安全验证。由此可知,抵御CSRF攻击的关键在于: 在请求中放入攻击者所不能伪造的信息,并且该信总不存在于cookie之中。鉴于此,系统开发人员可以在HTTP请求中以参数的形式加入一个随机产生的token,并在服务端进行token校验, 如果请求中没有token或者token内容不正确,则认为是CSRF攻击而拒绝该请求。 假设请求通过POST方式提交,则可以在相应的表单中增加一个隐藏域: <input type="hidden" name="_toicen" value="tokenvalue"/> token的值通过服务端生成,表单提交后token的值通过POST请求与参数一同带到服务端,每次会话可以使用相同的token,会话过期,则token失效, 攻击者因无法获取到token,也就无法伪造请求。 在session中添加token的实现代码: HttpSession session = request.getSession(); Object token = session.getAttribute("_token"); if(token == null I I "".equals(token)) { session.setAttribute("_token", UUID.randomUUIDO .toString()); } #4、通过Referer识别 根据HTTP协议,在HTTP头中有一个字段叫Referer,它记录了该HTTP请求的来源地址。在通常情况下,访问一个安全受限的页面的请求都来自于同一个网站。 比如某银行的转账是通过用户访问http://www.xxx.com/transfer.do页面完成的,用户必须先登录www.xxx.com,然后通过单击页面上的提交按钮来触发转账事件。 当用户提交请求时,该转账请求的Referer值就会是 提交按钮所在页面的URL(本例为www.xxx. com/transfer.do)。 如果攻击者要对银行网站实施CSRF攻击,他只能在其他网站构造请求,当用户通过其他网站发送请求到银行时,该请求的Referer的值是其他网站的地址,而不是银行转账页面的地址。 因此,要防御CSRF攻击,银行网站只需要对于每一个转账请求验证其Referer值即可,如果是以www.xx.om域名开头的地址,则说明该请求是来自银行网站自己的请求,是合法的; 如果Referer是其他网站,就有可能是CSRF攻击,则拒绝该请求。 取得HTTP请求Referer: String referer = request.getHeader("Referer");
四、django中防止csrf的方式
1、 默认打开csrf中间件。
Django默认启动了csrf防护,在settins.py文件中MIDDLEWARE_CLASSES中间件中的"django.middleware.csrf.CsrfViewMiddleware",
如果注释这行,表示关闭防御CSRF攻击,注意点: CSRF攻击只针正对post提交
2、 表单post提交数据时加上{% csrf_token %}标签。
开启Django中CSRF防御,且在表单中添加{% csrf_token %}, 那么在渲染模板文件时在页面生成一个名字叫做csrfmiddlewaretoken的隐藏域
五、django中防御csrf的原理
1、 渲染模板文件时在页面生成一个名字叫做csrfmiddlewaretoken的隐藏域。 2、 服务器交给浏览器保存一个名字为csrftoken的cookie信息。 3、提交表单时,两个值都会发给服务器,服务器进行比对,如果一样,则csrf验证通过,否则失败。
"一劳永逸" 的话,有是有的,而 "一劳永逸" 的事却极少
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」