跨站点请求伪造 (CSRF) 漏洞一直是对 Web 应用程序安全的严重威胁,它允许攻击者利用受害者的受信任会话执行未经授权的操作。为了应对这一挑战,JavaScript 提供了强大的工具来有效防范 CSRF 攻击。
1. 响应头设置
HTTP 响应头可用于向浏览器指示如何处理请求。通过设置以下响应头,可以阻止跨站点请求:
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
第一个响应头禁止将页面嵌入到其他域中,第二个响应头防止浏览器猜测内容类型,从而降低了跨站点脚本 (XSS) 攻击的风险。
2. 安全策略
Content Security Policy (CSP) 允许应用程序定义允许加载的脚本和资源白名单。通过限制只加载来自应用程序域的资源,可以有效预防 CSRF 攻击。
Content-Security-Policy: default-src "self"; script-src "self"
3. SameSite cookie
SameSite cookie 可以通过限制 cookie 的作用域来防止 CSRF 攻击。设置 SameSite 属性为 "Strict" 可以确保 cookie 仅在同源请求中发送,从而有效防止跨站点请求使用这些 cookie。
4. CSP 报告
CSP 报告 允许应用程序在违反 CSP 规则时接收报告。这使开发人员能够检测和修复潜在的 CSRF 漏洞。
Content-Security-Policy-Report-Only: default-src "self"
5. CSRF 令牌
CSRF 令牌 是一种随机生成的字符串,附加到每个请求。服务器验证令牌,如果令牌与预期值不匹配,则会拒绝请求。这可以防止攻击者在受害者的浏览器中执行未经授权的操作。
演示代码:
创建一个带有 CSRF 令牌的简单 HTML 表单:
<form action="/submit">
<input type="hidden" name="csrf_token">
<button type="submit">提交</button>
</form>
在服务器端,生成一个随机 CSRF 令牌并将其存储在会话中:
// 生成一个随机 CSRF 令牌
$csrf_token = bin2hex(random_bytes(32));
// 将令牌存储在会话中
$_SESSION["csrf_token"] = $csrf_token;
在表单提交时,通过 JavaScript 验证 CSRF 令牌:
const form = document.querySelector("form");
form.addEventListener("submit", (e) => {
e.preventDefault();
// 获取 CSRF 令牌
const csrf_token = form.querySelector("input[name="csrf_token"]").value;
// 使用 Fetch API 提交带有 CSRF 令牌的请求
fetch("/submit", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ csrf_token }),
})
.then((response) => {
if (response.ok) {
// 请求成功
} else {
// CSRF 令牌验证失败
}
});
});
结论:
通过采用这些 JavaScript 应对策略,Web 应用程序可以大大降低 CSRF 攻击的风险。通过实施响应头设置、安全策略、SameSite cookie、CSP 报告和 CSRF 令牌,开发人员可以有效保障应用程序的安全性并保护用户数据。