php不负责过滤cookie,需开发者主动校验、转义和白名单控制:①只读取预设键名并过滤;②对敏感值做强类型与范围校验;③输出时按html/js上下文转义;④remember me等关键场景用签名机制防篡改。

PHP 本身不负责“过滤 Cookie”,因为 Cookie 是客户端提交的原始数据,PHP 只是通过 $_COOKIE 读取它。所谓“未过滤 Cookie”,本质是开发者直接信任并使用 $_COOKIE 中的值,没做校验、转义或白名单控制——这会引发注入、XSS、逻辑绕过等风险。
关键不是“怎么防未过滤”,而是必须主动过滤、验证、限制使用场景。下面分几类实用做法:
明确声明可信键名,拒绝未知 Cookie
不要遍历 $_COOKIE 或用变量名拼接取值。只从预设白名单中读取,且立即校验格式:
$allowed = ['theme', 'language', 'timezone'];
$key = $_GET['pref'] ?? '';
if (in_array($key, $allowed) && isset($_COOKIE[$key])) {
$value = filter_var($_COOKIE[$key], FILTER_SANITIZE_STRING);
// 后续仅处理 $value,不拼接进 SQL/HTML/JS
}
对敏感 Cookie 值做强类型与范围校验
比如 theme=dark,不能只检查是否为字符串,还要确认是否在 ['light','dark','auto'] 中:
$theme = $_COOKIE['theme'] ?? '';
if (!in_array($theme, ['light', 'dark', 'auto'], true)) {
setcookie('theme', '', time() - 3600); // 清除非法值
$theme = 'light';
}
禁止将 Cookie 值直接输出到 HTML 或 JS 上下文
哪怕值看起来“安全”,也要按上下文转义:
// ❌ 危险
echo "<div class="user">Hello {$_COOKIE['name']}</div>";
// ✅ 正确
echo "<div class="user">Hello " . htmlspecialchars($_COOKIE['name'] ?? '', ENT_QUOTES, 'UTF-8') . "</div>";
// ❌ 危险(JS 注入)
echo "<script>var name = '{$_COOKIE['name']}';</script>";
// ✅ 正确
echo '<script>var name = ' . json_encode($_COOKIE['name'] ?? '', JSON_UNESCAPED_UNICODE) . ';</script>';
用签名机制识别篡改(尤其用于 remember me)
单纯加密不够,要服务端可验证。推荐方案:
- 生成随机 token 存数据库(明文不存,存 SHA-384 哈希)
- Cookie 中只放 token + 签名(如
token=abc123; sig=xyz789) - 每次请求时:查库比对哈希,并验证签名是否匹配原始 token
这样即使用户修改 cookie,服务端一验就失败。
不复杂但容易忽略。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











