当前位置:首页 > 技术 > 正文内容

跨站请求伪造(CSRF)攻击与防御机制

访客 技术 2026年7月6日 1

什么是CSRF攻击?

CSRF(Cross-Site Request Forgery,跨站请求伪造)是一种利用用户已登录的身份,在用户无感知的情况下执行恶意操作的安全漏洞。攻击者通过构造特定的请求链接或嵌入恶意内容,诱使用户在目标网站上执行非预期的操作。

例如:用户在登录某社交平台后,收到一封邮件,点击其中的链接,该链接实际上会自动向平台发送一条"发表动态"的请求,而用户并未主动提交表单。

此类攻击无需用户点击按钮,甚至仅刷新页面即可触发,尤其在使用GET请求时传播范围更广,危害性极高。攻击形式多样,包括链接、图片、表单等,可被用于转账、发帖、修改密码等敏感操作。

攻击原理剖析

CSRF攻击依赖于两个核心条件:

  1. 用户已在目标站点完成认证,浏览器保存了身份凭证(如Cookie)。
  2. 攻击者诱导用户访问含有恶意请求的页面,该请求会携带用户的认证信息自动发送至目标服务器。

由于浏览器在发起请求时会自动附带当前域名下的所有有效Cookie,因此即使攻击者无法获取这些数据,也能借助用户的登录状态完成非法请求。

典型危害场景

  • 未经授权的资金转移或消费
  • 以用户名义发布不当内容,导致声誉受损
  • 大规模传播恶意行为,形成类似网络蠕虫的效果

历史案例包括:某些平台因接口未校验来源,导致用户账户被批量扣费;社交媒体分享功能被利用,引发自动转发恶意消息的传播链。

防御策略详解

1. 利用 SameSite Cookie 属性

通过设置Cookie的 SameSite 属性,限制第三方上下文中的Cookie发送行为:

  • Strict:完全禁止跨站请求携带该Cookie,安全性最高。
  • Lax:允许部分导航请求(如直接访问链接)携带Cookie,但不包含大多数跨站表单提交。
  • None:允许跨站发送,但必须配合 Secure 属性(仅通过HTTPS传输)。

示例(Koa框架中设置):

ctx.cookies.set('sessionToken', token, {
  sameSite: 'strict',
  secure: true
});

注意:此方法依赖浏览器支持,部分旧版本浏览器可能不兼容。

2. 校验 Referer 头部信息

通过检查请求头中的 Referer 字段,判断请求是否来自可信源:

// PHP 示例
if (isset($_SERVER['HTTP_REFERER'])) {
    $referer = $_SERVER['HTTP_REFERER'];
    $allowedHosts = ['https://example.com', 'http://localhost'];
    
    $isValid = false;
    foreach ($allowedHosts as $host) {
        if (strpos($referer, $host) === 0) {
            $isValid = true;
            break;
        }
    }

    if (!$isValid) {
        http_response_code(403);
        exit('Forbidden: Invalid referer.');
    }
}

注意:Referer 可能被伪造或禁用(如本地文件访问),需结合其他措施使用。

3. 使用一次性 Token 验证

最有效的防御手段之一。在页面加载时生成一个随机令牌(Token),并同时存储在表单和Cookie中:

<!-- 前端生成并嵌入表单 -->
<form method="POST" action="/submit">
    <input type="hidden" name="csrf_token" value="abc123xyz">
    <textarea name="content">Hello</textarea>
    <button type="submit">提交</button>
</form>

<!-- 同时将 token 存入 cookie -->
<script>
document.cookie = "csrf_token=abc123xyz; path=/; SameSite=Lax";
</script>

后端在处理请求前验证表单中的Token与Cookie中的是否一致:

// 后端逻辑示例(Node.js + Express)
app.post('/submit', (req, res) => {
    const formToken = req.body.csrf_token;
    const cookieToken = req.cookies.csrf_token;

    if (!formToken || !cookieToken || formToken !== cookieToken) {
        return res.status(403).send('CSRF token mismatch');
    }

    // 正常处理业务逻辑
    res.send('Success');
});

对于多标签页场景,可通过前端动态刷新Token或设置失效机制来解决冲突问题。

4. 图形验证码(辅助手段)

要求用户完成人机验证才能提交表单,可有效阻止自动化攻击。但由于影响用户体验,通常仅用于高风险操作(如支付、改密)。

推荐使用成熟的验证码库(如 Node.js 中的 ccap),但不建议作为通用防护方案。

PHP 实现示例

以下为在 PHP 中实现多种防御方式的代码片段:

① 设置 SameSite Cookie

header('Set-Cookie: auth_token=abc123; SameSite=Lax; Secure; Path=/');

② Referer 校验

$referer = $_SERVER['HTTP_REFERER'] ?? '';
$allowed = ['https://yourdomain.com'];

if (!in_array($referer, $allowed)) {
    die('Access denied');
}

③ Token 防护

<?php
$token = bin2hex(random_bytes(16));
setcookie('csrf_token', $token, [
    'path' => '/',
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Lax'
];
?>

<form method="post">
    <input type="hidden" name="csrf_token" value="">
    <button type="submit">提交</button>
</form>

// 处理提交
if ($_POST['csrf_token'] !== $_COOKIE['csrf_token']) {
    die('Invalid token');
}

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。