[安全测试] 浅谈参数污染测试
原创内容未获授权禁止转载、转发、抄袭。接口测试时我们经常会测必填、类型、长度、边界值。但有一类问题很容易被忽略。就是参数污染。下面的示例只适用于授权测试环境。1. 什么是参数污染HTTP 参数污染简称 HPP。简单说就是攻击者在同一个请求里传多个同名参数利用后端对参数解析方式的差异影响业务逻辑。比如usernametest_userusernameadmin或者 JSON 请求体里出现重复字段{username:test_user,username:admin,password:******}重点不是请求能不能发出去。而是后端最终取了哪个值。这类测试最好用 Burp、Charles、Postman raw body 或curl构造原始请求。不要只在可视化参数表格里改。有些工具会自动去重导致测试请求根本没把重复字段发出去。核心原理Query、Form 这类参数层面同名参数可能会被传到服务端。JSON 重复字段则更依赖解析器和框架实现。不同后端框架对重复参数或重复字段的处理方式不一样。有的取第一个值有的取最后一个值有的拼接成字符串有的解析成数组如果业务代码没有显式校验就可能出现非预期结果。参数污染本身不一定是漏洞。但如果影响登录、支付、退款、权限、金额就是高风险问题。危害场景常见风险主要有两类。第一类是业务逻辑漏洞。比如登录成错误用户、支付金额被篡改、退款金额异常、订单状态被错误更新。第二类是绕过安全机制。比如绕过输入校验、绕过权限判断或者配合其他漏洞扩大影响范围。下面用两个例子说明。2. 例子1登录接口参数污染正常登录请求大概是这样{username:test_user,password:******,institutionId:ORG_ID}测试时可以把请求体改成{username:test_user,username:admin,password:******,institutionId:ORG_ID}这时不要只看接口是否返回成功。要继续验证最终登录身份。token 里是谁当前用户接口返回是谁页面展示的用户是谁会话表保存的是谁操作日志记录的是谁如果用普通用户密码最后登录成了管理员。这就不是普通参数问题。这是身份认证逻辑缺陷。进一步验证还要把两个username的顺序调换{username:admin,username:test_user,password:******,institutionId:ORG_ID}如果调换顺序后登录身份也跟着变化。说明后端很可能采用了“第一个值”或“最后一个值”的解析策略。测试结论不要写登录接口返回成功。而要写登录接口存在重复 username 参数解析风险调换字段顺序后登录身份发生变化可能导致身份认证被绕过。漏洞原理分析这里通常有几种可能。第一种覆盖策略。后端取最后一个username导致前面的值被覆盖。第二种首值策略。后端只取第一个username后面的值被忽略。第三种数组策略。解析器把重复字段处理成数组。如果业务代码期望字符串但实际拿到数组又没有做类型校验就可能出现异常逻辑。测试时要把解析策略写清楚。不要只记录“成功”或“失败”。3. 例子2支付接口金额污染支付接口更危险。因为参数污染一旦影响金额就可能造成直接经济损失。正常支付请求{orderId:ORDER_ID,model:1,paymentDetailList:[{type:PAY_TYPE,actualAmount:99.00,changeAmount:0}]}污染后的请求{orderId:ORDER_ID,model:1,paymentDetailList:[{type:PAY_TYPE,actualAmount:99.00,actualAmount:1.00,changeAmount:0}]}还可以继续验证极端金额场景。比如 0 元、负数、小数精度异常等。这类场景要重点验证实际支付金额是多少支付流水金额是多少订单原始金额是否被改动订单状态是否变成已支付财务记录是否一致是否出现低价买入、0 元购、倒贴金额支付接口不能信任前端传来的金额。服务端必须重新计算订单金额。漏洞根因这类问题一般不是单点原因。常见根因有三个。第一后端解析逻辑没有做重复参数检查。比如框架把 JSON 自动绑定成对象时默认接受了重复字段。publicclassPaymentRequest{privateListPaymentDetailpaymentDetailList;}publicclassPaymentDetail{privateBigDecimalactualAmount;}如果actualAmount重复出现框架可能取第一个也可能取最后一个。第二金额验证缺失。后端没有把前端传入金额和服务端订单金额做比对。第三业务流程设计有问题。比如创建订单时后端计算金额为 99.00用户发起支付时前端提交金额被篡改为 1.00后端只判断支付成功没有校验支付金额是否等于订单金额订单状态直接变成已支付这就是典型的业务一致性问题。4. 安全危害参数污染的危害取决于它影响了哪个业务字段。如果影响登录可能导致账户接管。如果影响权限可能导致越权访问。如果影响金额可能导致直接经济损失。如果影响订单状态可能导致业务流程错乱。尤其是这些字段需要重点关注usernameuserIdroleIdtenantIdorderIdamountactualAmountcouponIdstatus这些字段一旦被污染影响的通常不是页面展示。而是身份、金额、权限和数据归属。5. 修复建议第一严格输入校验。同一个字段只允许出现一次。发现重复参数直接拒绝。400 Bad Request第二关键参数不要信任客户端。金额、折扣、优惠、订单状态必须由服务端计算。第三身份和权限从服务端获取。用户身份应该来自 token 或服务端会话。不能信任前端传入的userId、username、roleId。第四支付流程要做双重校验。支付前校验订单状态支付前校验订单金额支付后校验支付流水异步任务核对订单和支付记录监控异常金额订单第五保留审计日志。支付、退款、权限变更类接口要记录原始请求、解析后参数和最终业务结果。总结参数污染测试不是看接口能不能接收重复参数。而是看重复参数有没有改变业务结果。登录场景要追最终身份。支付场景要追订单、流水和财务记录。权限场景要追真实数据访问范围。只要参数能影响身份、金额、权限就不能只看接口返回。要一直追到数据库、日志和最终业务状态。