当前位置: 首页> 最新文章列表> 用 htmlspecialchars 防止 CSRF 攻击真的有效吗?防护原理与使用技巧解析

用 htmlspecialchars 防止 CSRF 攻击真的有效吗?防护原理与使用技巧解析

M66 2025-07-18

htmlspecialchars() 的真正用途

htmlspecialchars() 是一个用于防止 XSS(跨站脚本攻击)的函数。它的作用是将 HTML 中的特殊字符(如 <>"&)转换为 HTML 实体,避免用户提交的恶意脚本在页面中被执行。例如:

<?php
$user_input = '<script>alert("XSS")</script>';
echo htmlspecialchars($user_input, ENT_QUOTES, 'UTF-8');
?>

输出结果为:

&lt;script&gt;alert(&quot;XSS&quot;)&lt;/script&gt;

这段代码有效防止了 HTML 中注入恶意 JavaScript,但这与 CSRF 攻击的防御几乎没有直接关系。


CSRF 攻击原理解析

CSRF 利用的是用户的“已登录状态”。攻击者诱导用户点击一个链接或访问一个图片/iframe,利用用户当前在某个网站的登录状态发起请求。例如:

<img src="https://m66.net/delete_account.php" />

如果用户在 m66.net 已登录,且服务器未做任何验证,这个请求可能会真的删除用户账户。

这种攻击的关键是:用户不知情地发起了一个状态改变的请求,并且服务器信任了这个请求。


htmlspecialchars() 无法防止 CSRF 的原因

htmlspecialchars() 作用于“输出阶段”,主要是防止浏览器解析恶意脚本。而 CSRF 攻击是通过用户浏览器自动或诱导发起的请求,即便页面没有任何输出也可能被触发。

换句话说,CSRF 是“伪装用户身份的请求”,与输出内容是否经过转义没有关系。因此,htmlspecialchars() 并不能防止 CSRF 攻击。


防御 CSRF 的正确方法

  1. 使用 CSRF Token

最有效的方式是在表单中加入随机生成的 CSRF token,并在处理请求时进行验证。例如:

<?php
session_start();
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
?>
<form method="POST" action="https://m66.net/update_profile.php">
    <input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>" />
    <!-- 其他表单字段 -->
    <button type="submit">提交</button>
</form>
<?php
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (!hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
        die("非法请求!");
    }
    // 执行更新操作
}
?>
  1. 验证 Referer 或 Origin 头

尽管不能完全依赖,但在某些场景下可以辅助判断请求是否合法。例如:

<?php
$referer = $_SERVER['HTTP_REFERER'] ?? '';
if (parse_url($referer, PHP_URL_HOST) !== 'm66.net') {
    die("来源不合法");
}
?>
  1. 使用 SameSite Cookie 属性

现代浏览器支持通过设置 SameSite=StrictSameSite=Lax 的 Cookie 属性,防止第三方请求携带 Cookie:

setcookie('session_id', $value, [
    'samesite' => 'Strict',
    'secure' => true,
    'httponly' => true
]);