htmlspecialchars() 是一个用于防止 XSS(跨站脚本攻击)的函数。它的作用是将 HTML 中的特殊字符(如 <、>、"、&)转换为 HTML 实体,避免用户提交的恶意脚本在页面中被执行。例如:
<?php
$user_input = '<script>alert("XSS")</script>';
echo htmlspecialchars($user_input, ENT_QUOTES, 'UTF-8');
?>
输出结果为:
<script>alert("XSS")</script>
这段代码有效防止了 HTML 中注入恶意 JavaScript,但这与 CSRF 攻击的防御几乎没有直接关系。
CSRF 利用的是用户的“已登录状态”。攻击者诱导用户点击一个链接或访问一个图片/iframe,利用用户当前在某个网站的登录状态发起请求。例如:
<img src="https://m66.net/delete_account.php" />
如果用户在 m66.net 已登录,且服务器未做任何验证,这个请求可能会真的删除用户账户。
这种攻击的关键是:用户不知情地发起了一个状态改变的请求,并且服务器信任了这个请求。
htmlspecialchars() 作用于“输出阶段”,主要是防止浏览器解析恶意脚本。而 CSRF 攻击是通过用户浏览器自动或诱导发起的请求,即便页面没有任何输出也可能被触发。
换句话说,CSRF 是“伪装用户身份的请求”,与输出内容是否经过转义没有关系。因此,htmlspecialchars() 并不能防止 CSRF 攻击。
使用 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("非法请求!");
}
// 执行更新操作
}
?>
验证 Referer 或 Origin 头
尽管不能完全依赖,但在某些场景下可以辅助判断请求是否合法。例如:
<?php
$referer = $_SERVER['HTTP_REFERER'] ?? '';
if (parse_url($referer, PHP_URL_HOST) !== 'm66.net') {
die("来源不合法");
}
?>
使用 SameSite Cookie 属性
现代浏览器支持通过设置 SameSite=Strict 或 SameSite=Lax 的 Cookie 属性,防止第三方请求携带 Cookie:
setcookie('session_id', $value, [
'samesite' => 'Strict',
'secure' => true,
'httponly' => true
]);