当前位置: 首页 > news >正文

CSRF(跨站请求伪造)攻击和预防

什么是 CSRF 漏洞?

当使用 cookie 进行会话管理的 Web 应用程序无法验证 HTTP POST 请求的来源时,通常会出现 CSRF(跨站点请求伪造)漏洞。

当 Web 应用程序通过使用 GET 方法进行更改而滥用 GET 方法时,也会发生这种情况。这两种情况都允许恶意网站代表登录用户执行不需要的操作。

如何防范 CSRF 漏洞?

按着这些次序。

  1. 使用您的应用程序平台/库提供的 CSRF 令牌。
  2. 请勿使用 POST、PUT、PATCH 或 DELETE 以外的其他 HTTP 动词进行更改。
  3. 使用“SameSite”指令保护您的 cookie。

同源政策

在开始之前,了解 SOP(Same Origin Policy)是很有帮助的,它是 Web 浏览器安全模型的核心和灵魂。这是一个或多或少说的规则:

  1. 如果两个 URL 的协议、端口(如果指定)和主机相同,则它们的来源相同。
  2. 任何来源的网站都可以自由地向任何其他GET来源发送、、、POST和请求。此外,该请求包括该来源的用户 cookie(包括会话 ID)。HEADOPTIONS
  3. 虽然可以发送请求,但来自一个来源的网站无法直接读取来自另一个来源的响应。
  4. 网站仍然可以从这些 HTTP 响应中消耗资源,例如通过执行脚本、使用字体/样式或显示图像。JSONP hack 利用了第四条规则(不要使用 JSONP)。
  5. 如果网站获得窗口句柄,则来自一个来源的网站可以限制访问另一个来源的窗口。最值得注意的是来自不同来源的窗口可以更改彼此的 URL ( anotherWindow.location.replace("https://www.evil.com")。

例如,这个网站的来源是在https://www.appsecmonkey.com/哪里,主机在哪里,并且没有指定端口(这是隐含的,因为协议)。protocolhttpswww.appsecmonkey.com443https

一个简单的例子

让我们假设用户可以像这样登录 AppSec Monkey 并更新他们的电子邮件地址:

POST /user/update-email/ HTTP/1.1
Host: www.appsecmonkey.com
Cookie: SessionId=ABC123
...

new_email=bob@example.com

后端代码可能看起来像这样(至少如果你使用 Django):

def update_email(request):
  new_email = request.POST['new_email']
  set_new_email(request.user, new_email)

现在假设有一个evil.example.com带有以下 HTML 表单和自动提交脚本的邪恶网站:

<form method="POST" action="https://www.appsecmonkey.com/user/update-email/">
  <input type="hidden" name="new_email" value="evil@example.com" />
</form>
<script type="text/javascript">
  document.badform.submit()
</script>

当当前登录的用户www.appsecmonkey.com进入恶意网站时,将代表用户自动提交 HTML 表单,并立即将以下 HTTP POST 请求发送到www.appsecmonkey.com

POST /user/update-email/ HTTP/1.1
Host: www.appsecmonkey.com
Cookie: SessionId=ABC123
...

new_email=evil@example.com

Bob 的电子邮件地址更改为evil@example.com.

CSRF 代币

防止这些攻击的常用方法是使用称为 CSRF 令牌的东西。它可以让您在 HTML 表单中添加一个隐藏的值,攻击者无法猜到。

<form method="POST" action="/user/update-email/">
  <input type="text" name="new_email" />
  <input type="hidden" name="csrf-token" value="SomeRandomValue123456" />
</form>

当另一个网站喜欢evil.example.com尝试提交表单时,网络服务器会拒绝 POST 请求,因为它不包含用户的 CSRF 令牌。

所有现代 Web 应用程序框架(Spring、Express、Symfony、Django、ASP.Net MVC等)。物有所值有这样的 CSRF 保护机制,所以不要创建自己的.

这是你的第一道防线。

不要忘记登录端点

它也是一个漏洞,通常可以通过某种方式利用,如果恶意网站可以在不知不觉中使用他们的帐户登录您的用户。

为防止这种情况,请确保在登录表单中也使用 CSRF 令牌。

您应该将令牌绑定到预身份验证会话(当用户进行身份验证并为用户提供新的会话 ID 时,您应该将其丢弃,但这是另一回事)。

或者,如果您使用 OAuth/OIDC,请确保您state正确验证了参数(有关详细信息,请参见此处)。

在这两种情况下,现代应用程序框架都应该能够毫不费力地处理它。

注意你的 HTTP 动词

CSRF-token 机制倾向于只保护 POST 请求。因此,如果您接受 GET 请求,例如https://www.appsecmonkey.com/user/update-email?new_email=evil@example.com,无论您可能使用任何 CSRF 保护,您通常都容易受到攻击。

确保您不使用除 POST/PUT/PATCH/DELETE 之外的任何东西进行更改。

现代平台倾向于明确动词,但有时您必须小心遗留框架。

使用 SameSite cookie

现在的浏览器支持一个很酷的特性,叫做SameSite cookie。当您使用 设置 cookie 时SameSite=Lax,浏览器不会将其包含在跨站点 POST 请求中。

Set-Cookie: SessionId=123; ...other options... SameSite=Lax

就是这样,简单而有效。但是不要仅仅依靠这个特性来保证你的应用程序的安全。使用 CSRF 令牌作为您的主要防御,并应用 SameSite cookie 作为额外的保护层。

您还可以在SameSite=Strict模式下设置 cookie。在这种情况下,GET 请求也将受到保护。但是,如果您遵循上述注意 HTTP 动词的规则,这对于 CSRF 保护来说不是必需的。而且它会在某种程度上破坏功能,因为指向应用程序的链接将不再按预期工作(在打开选项卡/窗口时将不再登录用户)。

使用该Strict变体的好处是可以防止某些 XSS(跨站点脚本)攻击,因此您可能至少要考虑一下。

使用无 cookie 会话管理

CSRF 是一个影响使用 cookie 进行会话管理的应用程序的漏洞。避免它们的一种方法是使用其他东西,例如 JavaScript 会话令牌。但这种方法也有缺点。例如,XSS 攻击可以访问令牌。相比之下,Web 应用程序可以使用该HttpOnly属性保护 cookie 免受 JavaScript 代码的影响。

结论

CSRF 攻击可能很危险。幸运的是,只要您使用支持 CSRF 令牌并明确 HTTP 动词的体面、现代的应用程序平台,它们也很容易避免。SameSite cookie 为您的应用程序提供了出色的附加安全层,但不应仅依赖于安全性。

相关文章:

  • 【都 Java17 了,还不了解 Java 8 ? 】一文带你深入了解 Java 8 新特性
  • 解决国产机SVN连接失败的问题
  • MySQL 存储过程创建指定表结构
  • 我们这样的人
  • < Linux > 进程概念(2)
  • Qt5开发从入门到精通——第四篇十二节(不规则窗体)
  • MySQL 5.7.x--命令行自带帮助文档的使用,超级棒!!!
  • 手撕前端面试题【javascript】
  • Qt5开发从入门到精通——第四篇十三节(程序启动画面 )
  • postman+Newman+jenkins实现接口自动化测试持续集成
  • 阿里达摩院(研究型实习生)
  • 汽车电子常用外围硬件电路设计
  • 猿创征文|半导体二极管
  • 《机器学习实战》学习笔记(十一)
  • 多态原理之虚函数表VBTL
  • 自己简单写的 事件订阅机制
  • 03Go 类型总结
  • codis proxy处理流程
  • CSS居中完全指南——构建CSS居中决策树
  • gops —— Go 程序诊断分析工具
  • Java小白进阶笔记(3)-初级面向对象
  • Median of Two Sorted Arrays
  • mongodb--安装和初步使用教程
  • Netty 4.1 源代码学习:线程模型
  • php的插入排序,通过双层for循环
  • php中curl和soap方式请求服务超时问题
  • python 学习笔记 - Queue Pipes,进程间通讯
  • Spring Cloud(3) - 服务治理: Spring Cloud Eureka
  • 聊聊springcloud的EurekaClientAutoConfiguration
  • 算法之不定期更新(一)(2018-04-12)
  • 网页视频流m3u8/ts视频下载
  • 微信支付JSAPI,实测!终极方案
  • 原生 js 实现移动端 Touch 滑动反弹
  • 第二十章:异步和文件I/O.(二十三)
  • ​你们这样子,耽误我的工作进度怎么办?
  • #我与Java虚拟机的故事#连载17:我的Java技术水平有了一个本质的提升
  • (2)nginx 安装、启停
  • (27)4.8 习题课
  • (4)通过调用hadoop的java api实现本地文件上传到hadoop文件系统上
  • (C#)Windows Shell 外壳编程系列4 - 上下文菜单(iContextMenu)(二)嵌入菜单和执行命令...
  • (ibm)Java 语言的 XPath API
  • (Java)【深基9.例1】选举学生会
  • (PWM呼吸灯)合泰开发板HT66F2390-----点灯大师
  • (笔试题)合法字符串
  • (二)hibernate配置管理
  • (附源码)spring boot建达集团公司平台 毕业设计 141538
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理 第13章 项目资源管理(七)
  • (一)Linux+Windows下安装ffmpeg
  • (一)RocketMQ初步认识
  • (译)2019年前端性能优化清单 — 下篇
  • (转)EOS中账户、钱包和密钥的关系
  • ***监测系统的构建(chkrootkit )
  • .NET Framework 的 bug?try-catch-when 中如果 when 语句抛出异常,程序将彻底崩溃
  • .NET 中使用 Mutex 进行跨越进程边界的同步
  • .NET/C# 项目如何优雅地设置条件编译符号?