同名参数为什么会出问题
当同一请求里出现多个同名参数时,不同技术栈的取值行为并不一致:有的取第一个,有的取最后一个,有的变成数组。如果安全校验组件与业务逻辑组件读取的方式不同,攻击者就能构造出让校验看到 A、业务执行 B 的请求,绕过参数校验、权限判断或金额校验。
基本信息
| 表现形式 | ?role=user&role=admin 这类重复参数 |
|---|---|
| 成因 | 前后端与各框架的解析行为不一致 |
| 高危参数 | 权限角色、金额、审批状态、文件路径 |
| 防护位置 | 网关统一策略 + 应用内单一解析口径 |
| 测试要点 | 构造重复参数验证校验与取值是否一致 |
典型使用场景
- 权限校验绕过:安全组件取第一个值,业务取值取最后一个
- 金额与折扣:重复参数导致校验金额与实际下单金额不一致
- WAF 与后端差异:WAF 按一种规则解析,后端按另一种
- 参数注入链:与 SQL 注入或开放重定向组合放大效果
- 测试验证:在回归用例中固定加入重复参数场景
行为差异示例
行为差异示例
?role=user&role=admin
PHP 默认取最后一个(admin)
JSP/Servlet 默认取第一个(user)
Node/Express 解析为数组 ['user','admin']
ASP.NET 常合并为逗号分隔字符串 "user,admin"
# 结论:同一个请求在不同组件里可能得到不同结论防护动作
防护动作
1. 网关层统一策略:重复参数直接拒绝,或按约定规范化后再转发
2. 应用层显式声明参数的取值语义(单值还是多值)
3. 安全校验与业务取值使用同一解析结果,禁止各解析一次
4. 回归测试加入重复参数用例,覆盖权限与金额类接口技术栈取值行为
| 技术栈 | 取值行为 | 注意点 |
|---|---|---|
| PHP | 取最后一个同名参数 | 校验与使用位置都要一致 |
| JSP/Servlet | getParameter 取第一个 | 数组接口可拿到全部值 |
| Node/Express | 解析为数组 | 取数组首项或末项语义要显式 |
| ASP.NET | 常合并为逗号分隔字符串 | 分隔符出现在输入中会产生歧义 |
涉及权限与金额的参数要统一解析口径:网关、框架、业务代码各解析一次,就存在三次结论不一致的机会,收敛方式是只解析一次并把结果向下传递。
WAF 与后端解析不一致是典型绕过路径:WAF 只看第一个参数值、后端取最后一个时,攻击载荷可以完整送达后端,因此网关层应以拒绝重复参数为默认策略。