CSRF(Cross-Site Request Forgery,跨站哀求伪造)攻击是一种答应攻击者通过受害者的身份执行非预期操作的安全威胁。为了防御这种攻击,前端开发者通常必要联合后端验证和特定的前端计谋。
令牌验证:
这是最常用的防御手段,通常涉及生成一个CSRF令牌,并将其在客户端和服务器之间交换。
服务器生成令牌:
在用户登录成功后,服务器生成一个CSRF令牌,并将其存储在用户的会话中。
- # Python 示例
- from flask import Flask, session
- app = Flask(__name__)
- @app.route('/login')
- def login():
- session['csrf_token'] = generate_csrf_token()
- return render_template('login.html', csrf_token=session['csrf_token'])
复制代码 客户端使用令牌:
将令牌嵌入到每个必要防护的表单中,或者作为HTTP头的一部分。
- <!-- HTML 示例 -->
- <form action="/protected" method="POST">
- <input type="hidden" name="csrf_token" value="{{ csrf_token }}">
- <!-- ...其他表单字段... -->
- </form>
复制代码- // JavaScript 示例(使用Fetch API)
- fetch('/protected', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/x-www-form-urlencoded',
- 'X-CSRF-Token': window.csrfToken
- },
- body: formData
- });
复制代码 检查Referer头:
虽然不完全可靠,因为Referer头可以被浏览器禁用或篡改,但通常可以作为辅助防御措施。
- # Python 示例(Flask中间件)
- from flask import request
- @app.before_request
- def check_referer():
- if request.method in ['POST', 'PUT', 'DELETE']:
- if not request.referrer or request.referrer != app.config['APP_BASE_URL']:
- return abort(403)
复制代码 双因素认证:
要求用户在提交敏感操作前举行二次确认,比方通过弹窗或验证码。
SameSite Cookie属性:
设置Cookie的SameSite属性为Lax或Strict,限制跨站提交。Lax模式答应在top-level导航中发送,而Strict模式则更严酷,只在同一站点内的哀求中发送。
- # Python 示例(使用Flask-Session扩展)
- from flask_session import Session
- from flask import Flask
- app = Flask(__name__)
- Session(app)
- app.session_interface.cookie_samesite = 'Lax'
复制代码 POST-only接口:
对于敏感操作,只接受POST哀求,不使用GET哀求,因为GET哀求容易被浏览器书签、链接预加载或第三方脚本滥用。
前端代码中,防御CSRF通常涉及在表单提交或Ajax哀求时附带CSRF令牌。确保在后端验证令牌的有用性是至关重要的,因为前端的防御措施可以被绕过。
以下是一个Node.js + Express + CSRF掩护的示例:
- // server.js
- const express = require('express');
- const bodyParser = require('body-parser');
- const csrf = require('csurf');
- const app = express();
- // 使用cookie-parser中间件解析cookie
- app.use(require('cookie-parser')());
- // 使用中间件生成和注入CSRF令牌
- const csrfProtection = csrf({ cookie: true });
- app.use(csrfProtection);
- // 保护路由
- app.post('/protected', csrfProtection, (req, res) => {
- // 验证令牌并执行操作
- if (req.csrfToken() === req.body.csrfToken) {
- // 安全的操作
- } else {
- // CSRF令牌无效,返回错误
- res.status(403).send('CSRF token mismatch');
- }
- });
- // 响应HTML页面,包含CSRF令牌
- app.get('/', (req, res) => {
- res.send(`
- <form action="/protected" method="POST">
- <input type="hidden" name="csrfToken" value="${req.csrfToken()}">
- <button type="submit">Submit</button>
- </form>
- `);
- });
- app.listen(3000);
复制代码 使用CSP(Content Security Policy)
内容安全计谋(CSP)是一种网络安全计谋,通过指定哪些外部资源可以被加载或执行,来减少跨站脚本攻击的风险。虽然CSP重要针对XSS攻击,但它也能间接帮助防御CSRF,特殊是当CSP配置得当,限制了第三方网站对你的应用发起哀求的能力时。
- // 在Express应用中设置CSP头部
- app.use((req, res, next) => {
- res.setHeader("Content-Security-Policy", "default-src 'self'; script-src 'self' 'unsafe-inline'");
- next();
- });
复制代码 验证HTTP哀求头的Origin字段
只管不如使用CSRF令牌可靠,但在某些场景下检查Origin头部也可以作为一种辅助防御措施。如果哀求来自不受信托的源,服务器可以选择拒绝该哀求。
- # Flask示例
- from flask import request
- @app.before_request
- def verify_origin():
- if request.method == 'POST':
- allowed_origins = ['https://your-trusted-origin.com']
- origin = request.headers.get('Origin')
- if origin not in allowed_origins:
- return 'Unauthorized', 401
复制代码 HSTS(HTTP Strict Transport Security)
强制浏览器只通过HTTPS与服务器通讯,可以防止中间人攻击,从而低落CSRF攻击的风险,因为攻击者更难以拦截或修改HTTPS通讯。
- # Flask示例
- @app.after_request
- def apply_hsts(response):
- response.headers['Strict-Transport-Security'] = 'max-age=31536000; includeSubDomains'
- return response
复制代码 使用Web应用防火墙(WAF)
Web应用防火墙可以提供额外的防护层,检测并阻止恶意哀求,包罗CSRF攻击。WAF可以是硬件装备、软件服务或云服务,通常基于署名匹配、举动分析或呆板学习算法来识别和阻止攻击。
限制敏感操作的频率
限制用户执行敏感操作的速率可以帮助防止大规模的CSRF攻击。比方,限制用户在一分钟内只能提交反复更改密码或删除账户的哀求。
- // 使用JavaScript实现简单的速率限制
- let lastRequestTime = null;
- const LIMIT = 60 * 1000; // 一分钟
- function submitSensitiveAction() {
- const currentTime = Date.now();
- if (lastRequestTime && currentTime - lastRequestTime < LIMIT) {
- alert('Too many requests, please try again later.');
- return;
- }
-
- // 提交请求...
- lastRequestTime = currentTime;
- }
复制代码 制止使用GET哀求举行敏感操作
虽然POST哀求通常被以为比GET哀求更安全,但某些情况下,GET哀求可能不可制止。在这种情况下,确保URL不会被缓存或记录在浏览器汗青记录中,以低落CSRF风险。比方,使用动态生成的随机参数,而不是直接暴露敏感信息。
- # Django示例
- from django.http import HttpResponseBadRequest
- def sensitive_get_view(request):
- if not request.GET.get('random_token') == request.session.get('random_token'):
- return HttpResponseBadRequest('Invalid token')
- # 执行敏感操作...
- # 清除随机令牌,防止重放攻击
- request.session.pop('random_token', None)
复制代码 思量使用OAuth 2.0或JWT
现代Web应用经常使用OAuth 2.0或JSON Web Tokens (JWT)举行身份验证。这些协议提供了内置的机制来验证哀求的来源和授权状态,从而低落CSRF攻击的风险。然而,正确实现这些协议同样至关重要,因为它们也有自己的安全挑战。
保持框架和库的更新
确保你使用的前端框架、后端库和服务器软件都保持最新,以便得到最新的安全补丁和修复。
安全编码和测试
遵照安全编码最佳实践,如输入验证、输出编码、错误处理和日志记录,可以帮助发现和修复潜在的弊端。别的,定期举行安全测试,如渗透测试和代码审查,可以确保应用在发布之前是安全的。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |