cookie值直接拼入sql是明摆着的高危漏洞,修复关键在于切断用户可控输入到sql拼接的链路;因cookie可被浏览器工具、curl等任意篡改,故须用白名单校验或强类型转换(如in_array或(int)),而非简单过滤单引号。

Cookiе 值直接拼进 SQL 就是漏洞,不是“隐藏式”,是明摆着的高危操作。 修复它不靠加一层加密或混淆,而是切断“用户可控输入 → SQL 字符串拼接”这条链路。
为什么 $_COOKIE['xxx'] 不能直接进 SQL
开发者常误以为 Cookie 是自己写入的、客户端改不了,但实际:
– 浏览器开发者工具可任意修改 document.cookie
– curl、Postman、Burp Suite 都能重放并篡改 Cookie 头
– 登录态、角色、语言偏好等字段常存于 Cookie,又常被用于 WHERE 条件
典型危险写法:$role = $_COOKIE['user_role']; $sql = "SELECT * FROM users WHERE role = '$role'";,攻击者设 user_role=admin' -- 即可绕权
必须用白名单或强类型校验,而不是过滤单引号
“过滤掉 '” 是无效防御,绕过方式太多(如用 /**/UNION/**/SELECT、十六进制编码、宽字节等)。真正有效的做法是按字段语义做约束:
- 若
user_role只能是admin、member、guest:用in_array($_COOKIE['user_role'], ['admin','member','guest'])校验,不匹配就拒访 - 若
user_id应为正整数:写成$uid = (int)$_COOKIE['user_id']; if ($uid - 若
token是 32~64 位字母数字:用preg_match('/^[a-zA-Z0-9]{32,64}$/', $_COOKIE['token']),不通过就中断流程
所有 Header 字段一律禁止进 SQL 查询逻辑
$_SERVER['HTTP_USER_AGENT']、$_SERVER['HTTP_REFERER']、$_SERVER['HTTP_X_FORWARDED_FOR'] 等字段完全由客户端控制,内容不可信且格式无规律。历史上真实案例:攻击者在 User-Agent 中塞入 ' OR 1=1 --,配合后台日志分析功能导致报错泄露表结构。
如果真要记录这些字段:
- 只允许存入专用日志表,该表字段类型为
TEXT,且不参与任何WHERE/JOIN查询 - 或先用
htmlspecialchars()转义 + 截断至 255 字符再入库 - 绝对不要为“调试方便”把它们拼进主业务 SQL
参数化查询是兜底手段,但不能替代输入校验
即使用了 PDO 的 prepare() + bindValue(),如果传入的是未校验的 $_COOKIE 值,仍可能引发逻辑错误或越权(比如查到不该看的数据)。所以正确顺序是:
- 先校验
$_COOKIE值是否符合预期语义(类型、范围、格式) - 再用参数化方式带入 SQL
- 数据库连接账号权限最小化(如只授予
SELECT,不给DROP或FILE)
最易被忽略的一点:框架自动解包后的 $_COOKIE 看起来像普通变量,反而更容易被无意识拼接——别信来源,只信校验结果。










