能,user-agent可被用于sql注入。因部分web应用未对请求头参数做参数化处理,直接将其拼入insert或update语句(如insert into logs (ua, ip, time) values ('{user_agent}', '{ip}', now())),攻击者可通过构造' or sleep(5)--等payload触发报错、盲注或延时响应。

SQL注入能从User-Agent里进来吗
能,而且真实发生过。很多Web应用把 User-Agent 值直接拼进日志 SQL 或用户行为分析语句里,比如:INSERT INTO logs (ua, ip, time) VALUES ('{user_agent}', '{ip}', NOW())。一旦没做参数化,攻击者在请求头里塞 ' OR '1'='1,就可能触发报错或盲注。
常见错误场景包括:
- 后台用
mysqli_query()或sqlite_exec()拼接User-Agent字符串,没走prepare/bind - 日志中间件(如自研访问统计模块)把请求头原样写入数据库
- WAF规则只拦
GET/POST参数,忽略HTTP headers的可执行上下文
Referer字段为什么比GET参数更危险
Referer 不仅能带恶意 payload,还常被绕过前端校验——因为它是浏览器自动带上、服务端很少主动校验的字段。比如某电商后台按 Referer 判断来源渠道,再把该值存入订单表的 source 字段:UPDATE orders SET source = '{referer}' WHERE id = 123。
关键风险点:
- Referer 值不受前端 JavaScript 校验约束(用户可禁用 JS 或手动构造请求)
- 某些 CDN 或反向代理会重写或清空 Referer,导致后端逻辑误判并 fallback 到不安全的默认处理
- 部分 ORM 框架(如旧版 ThinkPHP 3.x)的
where()方法若传入数组且 key 是动态字段名,Referer可能被当作字段名参与解析
过滤这两个字段的实际操作建议
不是简单 replace 单引号或分号,而是要匹配业务语义做白名单清洗。例如:
- 对
User-Agent:只保留 ASCII 字母、数字、空格、斜杠、括号、点、短横线,长度限制在 256 字节以内;拒绝含UNION、SELECT、EXEC等关键字的 UA(注意大小写和编码绕过) - 对
Referer:先校验是否为合法 URL 格式(用filter_var($referer, FILTER_VALIDATE_URL)),再提取 host 部分做域名白名单比对;非站内来源一律置为空或固定字符串external - 所有入库前必须强制走参数化查询,哪怕只是插入日志——
INSERT INTO logs (ua) VALUES (?)比任何正则过滤都可靠
为什么 WAF 规则常在这里失效
很多商业 WAF 默认只检测 GET 和 POST body,把 User-Agent 和 Referer 归类为“低风险头”,甚至不进 SQLi 规则引擎。更麻烦的是,某些 WAF 对 header 做了长度截断(比如只检查前 128 字节),而攻击者把 payload 放在 UA 后半段就能绕过。
验证方法很简单:用 curl 手动发一个带 payload 的请求:
curl -H "User-Agent: Mozilla/5.0 (X11; Linux x86_64) ' OR SLEEP(5)-- " http://example.com/
如果响应延迟明显,说明后端没过滤也没参数化——这时候别信 WAF 日志里写的“已拦截”。
真正难防的不是单次注入,是那些把 User-Agent 当作 session 上下文、又混用在权限判断里的逻辑链。这种地方一漏,头信息就成了跳板。











