Web安全实习: 跨站请求伪造 (CSRF) 😱🛡️

发布: (2025年12月18日 GMT+8 15:45)
5 min read
原文: Dev.to

Source: Dev.to

引言

大家好,亲爱的同学们!欢迎来到关于 Cross‑Site Request Forgery (CSRF) 的实践课程,这是最狡猾的网络攻击之一。想象一下,你正在登录网银,然后打开另一个标签页访问恶意网站。你不知情的情况下,恶意网站可以“强迫”你的浏览器向银行发送请求,将钱转给黑客,而你并没有点击任何东西。这是因为浏览器会自动在向其他域发送请求时附带身份验证 cookie。

CSRF 是 伪造请求,利用浏览器对会话 cookie 的信任,从其他站点发起请求。

CSRF 工作原理

主要条件

  1. 用户已登录 – 有有效的会话 cookie。
  2. 重要操作(例如转账、修改密码、删除账户)使用 GETPOST 方法且没有防护。
  3. 浏览器在每次请求时会自动向原始域发送 cookie。

攻击流程(经典示例)

  1. 受害者 已登录目标站点后访问恶意站点。
  2. 恶意站点加载元素(例如图片或隐藏表单),向目标站点发送请求。
  3. 受害者的浏览器连同会话 cookie 一起发送请求,从而在受害者不知情的情况下执行危险操作。

CSRF 攻击流程示意图

Source:

示例漏洞

1. 使用 GET 的银行转账

GET http://bank.com/transfer?jumlah=1000000&rekening_tujuan=12345678 HTTP/1.1
Host: bank.com
Cookie: session=abcd1234

恶意网站 可以插入隐藏图片:

![](http://bank.com/transfer?jumlah=5000000&rekening_tujuan=hacker123)

当受害者打开恶意页面时,浏览器会自动向黑客账户发送转账请求。

2. 脆弱表单(POST 未加保护)

<form action="/ubah-email" method="POST">
    <input type="email" name="email" value="hacker@example.com">
    <button type="submit">Simpan</button>
</form>

恶意网站

<script>
    document.getElementById('jahat').submit();
</script>

打开恶意页面的受害者会自动提交该表单,从而把账户邮箱改为黑客所有。

3. 使用 GET 的 “点赞” 操作

示例请求:GET /post?id=123&action=like
恶意网站可以添加图片标签:

![](http://target.com/post?id=123&action=like)

保护机制

CSRF Token(最常用且强大)

  1. 服务器 为每个会话或每个表单生成唯一 token。
  2. Token 作为隐藏字段或自定义 header 放入表单中。
  3. 服务器 在处理请求前验证 token。
<form action="/simpan" method="POST">
    <input type="hidden" name="csrf_token" value="RANDOM_TOKEN">
    <button type="submit">Simpan</button>
</form>

如果 token 不匹配或不存在,服务器会拒绝请求。

设置 cookie 时使用 SameSite=LaxSameSite=Strict,使浏览器在跨站请求时 不发送 cookie。

Set-Cookie: session=abcd1234; SameSite=Strict; Secure; HttpOnly

其他最佳实践

  • 使用 POST 进行会改变状态的操作,避免使用 GET。
  • 双提交 Cookie:将 token 同时作为 cookie 和表单参数发送。
  • 利用 框架自带的防护(Laravel、Django、Spring Security 等),它们会自动添加并验证 token。

附加:CSRF vs XSS 🆚

方面CSRFXSS
目标浏览器对 Cookie 的信任在页面中插入脚本
工作原理强制使用有效 Cookie 发起请求注入在受害者浏览器中执行的脚本
常见影响不期望的操作(转账、数据更改)数据窃取、会话劫持、页面篡改
主要缓解措施CSRF Token、SameSite Cookie、POST输入过滤、CSP、HttpOnly Cookie

实践与实验

  • 在 PHP 中创建易受攻击的转账表单,并使用图片标签测试 CSRF 攻击。
  • 添加 手动 CSRF 令牌 并重新测试;请求应当失败。
  • PortSwigger Web Security Academy(搜索 “CSRF”)尝试免费实验。

讨论

  • 为什么许多银行将 token CSRFOTP 结合使用?
  • 如何确保所有状态更改的端点都受到保护?

祝实践愉快!通过了解 CSRF 并实施适当的防护,你的 Web 应用将像银行金库一样安全。始终保护会改变状态的操作,并持续养成安全编码的习惯。 🎉🔐

Back to Blog

相关文章

阅读更多 »

交互式流体排版

请提供您希望翻译的具体摘录或摘要文本,我才能为您进行简体中文翻译。

请尝试 Htmx

文章链接: http://pleasejusttryhtmx.com/ 评论链接: https://news.ycombinator.com/item?id=46312973 积分: 104 评论: 107