cookie值直接拼入sql是高危操作,因其可被任意篡改,必须按语义白名单校验或强类型转换,禁止简单过滤;header字段同理,须隔离存储并严格长度与转义处理。

Cookie 值进 SQL 就是高危操作,不校验=裸奔
为什么 $_COOKIE['xxx'] 不能直接拼进 SQL
很多人误以为 Cookie 是“自己写的、浏览器发回来的,所以可信”,但实际中:$_COOKIE 完全可被篡改——用浏览器开发者工具、curl、Fiddler 都能轻松修改;user_role、user_id、session_token 这类字段又常被用于 WHERE 条件或权限判断。一旦写成 $sql = "SELECT * FROM users WHERE role = '{$_COOKIE['role']}'",攻击者只需把 role 设为 admin' --,就能绕过整个权限逻辑。
必须按语义做白名单或类型强转,不是简单过滤单引号
“过滤掉单引号”这种操作早已失效,且容易漏判(比如用十六进制、Unicode 编码绕过)。真正有效的做法是结合字段含义做约束:
- 若
user_role只允许admin、member、guest:用in_array($_COOKIE['user_role'], ['admin', 'member', 'guest'])校验,不匹配就die()或返回 400 - 若
user_id是数字 ID:强制转整型$uid = (int)$_COOKIE['user_id'];,再检查是否 > 0 - 若
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 --,配合后台日志查询功能,直接触发 SQL 报错泄露表结构。
如果真要记录这些字段:
- 只允许存入专用日志表,且该表字段类型为
TEXT,不参与任何WHERE、JOIN或ORDER BY - 入库前必须截断长度(如限制 255 字符)+
htmlspecialchars()转义,禁止原样拼接 - 绝不要为了“临时调试”把它们写进 SQL 查询字符串里
最易被忽略的一点:框架自动解包后的 $_COOKIE 看起来像普通变量,但语义上它和 $_GET 一样属于外部输入源——只要进了 SQL 拼接,就等于把数据库钥匙交到用户手上。










