参数篡改如何防护校验

wen 开源项目 28

本文目录导读:

参数篡改如何防护校验

  1. 最核心原则:永远不信任客户端
  2. 参数级校验:明确数据边界
  3. 会话与权限级防护:防御越权篡改
  4. 参数传递与签名机制:防止中间人篡改
  5. 后端架构与框架级防御

参数篡改是一种常见的Web安全威胁,攻击者通过修改客户端发送的请求参数(如URL查询字符串、表单字段、Cookie、HTTP头等)来达到越权、数据窃取或系统破坏的目的,防护的核心是对每一条到达服务端的参数都进行严格的校验

以下是从代码、架构到运维层面的全方位防护校验方案:

最核心原则:永远不信任客户端

任何来自客户端(浏览器、APP、桌面端)的数据都是不可信的,所有校验必须在服务端进行,客户端的校验仅用于提升用户体验,不具安全性。


参数级校验:明确数据边界

类型与格式校验

  • 强类型语言:使用DTO(数据传输对象)或实体类进行类型绑定。
    • 例:int age = Integer.parseInt(request.getParameter("age")); 如果参数不是整数,直接抛出异常。
  • 正则表达式:对字符串类型参数进行格式匹配。
    • 邮箱:^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
    • 手机号:^1[3-9]\d{9}$
  • 枚举校验:对于状态、类别等有限集合的参数,使用枚举或白名单列表。
    • 例:status 只能是 [0, 1, 2],如果传了 999,直接拒绝。

长度与范围校验

  • 数值范围0 < price <= 10000,防止越界注入或逻辑错误。
  • 字符串长度:限制输入最大长度,防止缓冲区溢出或存储攻击。
    • 例:username.length() <= 50
  • 数组长度:限制一次提交的批量数量(如最大100条),防止批量篡改或DoS攻击。

枚举值与白名单校验

  • 危险参数:如 role=adminisVip=trueaction=delete
  • 方案:服务端必须内置映射关系,而非直接信任客户端传来的值。
    • 错误做法:根据 ?role=admin 直接赋予管理员权限。
    • 正确做法:从Session或Token中解析当前用户的真实角色,忽略 role 参数。

业务逻辑一致性校验

  • 不可编辑字段:如订单金额、积分、创建时间等,前端不展示或展示为只读,后端应忽略或覆盖前端传来的该参数值。
  • 计算校验:如果参数存在内在关联,需校验一致性。
    • 例:totalPrice = unitPrice * quantity,后端应重新计算 totalPrice,与前端传入值做比对,若不匹配则拒绝。

会话与权限级防护:防御越权篡改

基于Session/Token的权限校验

  • 用户ID篡改:攻击者尝试修改 userId=100 来查看他人信息。
    • 防护:永远不要从请求参数中读取当前用户ID,从服务端Session或JWT Token中解析 当前登录用户ID
    • 例:Long currentUserId = SecurityContextHolder.getCurrentUser().getId();

资源所有权校验

  • 即使攻击者知道了正确的用户ID,也要校验他是否有权操作该资源。
  • 例:修改订单 orderId=888,需校验 order.userId == currentUserId

CSRF(跨站请求伪造)防护

  • 攻击者诱导用户点击一个恶意链接,利用用户的登录状态发送篡改参数的请求。
  • 防护
    • 使用CSRF Token(前后端分离常见使用)。
    • 使用SameSite=StrictLax的Cookie属性。
    • 关键操作(支付、删除)使用二次验证(如短信验证码)。

参数传递与签名机制:防止中间人篡改

使用数字签名(HMAC/RSA)

  • 原理:将参数按一定规则排序后,与密钥拼接,计算哈希值(MD5/SHA256)作为签名。
  • 流程
    1. 服务端下发一个 secretKeyappId + secret
    2. 客户端对参数排序(如按字母顺序)并拼接成 str=A=1&B=2&C=3
    3. 计算 sign = HMAC-SHA256(secret, str)
    4. 服务端收到请求后,用同样的 secret 计算并比对 sign
  • 效果:参数被篡改后,签名校验失败,直接拒绝。

防重放攻击(时间戳+随机数Nonce)

  • 即使参数及签名被拷贝,攻击者在短时间内重新发送请求。
  • 方案
    • 请求携带 timestamp(Unix毫秒时间戳)。
    • 服务端比对时间差(如 |now - timestamp| >= 5分钟 则拒绝)。
    • 结合 nonce(一次性随机字符串),服务端记录已使用的nonce,防止5分钟内重复使用。

参数加密(敏感数据)

  • 敏感参数:如银行卡号、密码、身份证号。
  • 方案:使用对称加密(AES)或非对称加密(RSA)对参数整体或部分加密,服务端解密后再使用,攻击者无法解密也就无法篡改。

后端架构与框架级防御

使用成熟的校验框架

  • JavaBean Validation (JSR 303/380) 配合注解(@NotNull, @Size, @Pattern, @Digits)。
  • PythonPydantic, marshmallow
  • Node.jsJoi, express-validator
  • Govalidator 包。
  • 所有语言:Web框架自带的校验中间件(如Spring的 @Validated, Django的 ModelForm)。

输入净化与转义

  • SQL注入防护:使用参数化查询(Prepared Statement),禁止拼接SQL字符串。

抱歉,评论功能暂时关闭!