电商订单页安全处理POST提交易篡改数据的最佳实践
彻底摒弃对前端敏感数值的信任
前端hidden字段、AJAX传递的总价、折扣、数量这类数据,只能作为展示用,绝对不能直接用于后端的金额计算或订单入库。提交订单时,后端只需要获取用户ID、商品ID/规格ID、优惠券ID这几个核心标识,然后自行从数据库拉取真实数据重新计算:- 通过商品ID查询商品原价、实时库存(顺便校验库存是否充足,避免超卖)
- 通过优惠券ID查询折扣规则,校验该优惠券是否对当前用户、当前商品有效,计算真实折扣金额
- 根据用户提交的商品数量,结合数据库中的商品单价,重新核算商品总价
举个实际场景:前端传过来总价100、折扣20,但后端要独立计算:商品单价50×数量2=100,优惠券满100减20,最终应付80,完全忽略前端传递的数值。
用服务端会话存储订单临时状态
用户选商品、选优惠券的过程中,把这些选择的核心数据(商品ID、数量、优惠券ID)存在服务端的Session或Redis中,不要依赖前端存储。比如用户选择优惠券时,AJAX请求后端,后端先校验优惠券有效性,通过后把优惠券ID存入用户会话,再把计算后的总价返回给前端展示。
提交订单时,后端从会话中取出之前保存的商品、优惠券信息,再和数据库数据做二次校验,避免前端中途篡改会话外的参数。给AJAX请求加签名防篡改
针对切换优惠券这类AJAX交互,后端可以生成请求签名(比如用HMAC算法,把用户ID、商品ID、优惠券ID、当前时间戳等参数,加上后端专属密钥生成哈希值),将签名和参数一起返回给前端。
前端后续请求(比如更换优惠券)时必须携带这个签名,后端收到请求后,用相同的算法重新生成签名并比对,不一致则直接拒绝请求,防止黑客篡改AJAX请求里的优惠券ID、数量等关键参数。强化权限与有效性校验
- 优惠券校验:检查是否过期、是否已被使用、是否满足使用门槛(如满减金额、适用商品范围)、是否属于当前用户(防止盗刷他人优惠券)
- 库存校验:提交订单时必须再次校验库存,同时用数据库事务或乐观锁机制,避免并发下单导致的超卖问题
- 用户身份校验:确保订单与当前登录用户绑定,后端要校验提交订单的用户ID与登录态一致,防止恶意提交他人信息
隐藏字段仅做展示辅助
前端hidden input里的总价、折扣价,只是给用户做展示参考,后端绝对不要读取这些值来计算应付金额。哪怕渲染页面时后端把计算好的总价存在hidden里,提交订单时也直接忽略,完全靠后端重新核算。添加异常监控与日志
记录所有订单提交请求的详细日志,包括前端传递的参数和后端计算的真实参数,一旦发现两者差异过大(比如前端传的总价远低于后端计算值),标记为异常请求并触发告警。
对频繁提交异常参数的IP或用户,执行临时封禁,防范恶意攻击。
内容的提问来源于stack exchange,提问作者Jin Singh

