【web应用安全】关于web应用安全的几个主要问题的思考-防重放攻击

时间:2025-03-29 09:44:43

在Web应用中,重放攻击(Replay Attack) 是指攻击者截获用户的有效请求后,重新发送该请求以伪造操作(如重复支付、越权访问等)。以下是防御重放攻击的常用方法及原理分析:

1. Token机制(一次性令牌)

  • 原理
    • 服务器生成唯一Token(如UUID),返回给客户端。
    • 客户端需在后续请求中携带该Token。
    • 服务器验证Token有效性后立即失效(如删除或标记为已使用)。
  • 实现
    // 登录后返回Token
    HTTP/1.1 200 OK
    Set-Cookie: csrf_token=abc123; HttpOnly; Secure
    
    // 请求需携带Token
    POST /transfer HTTP/1.1
    Cookie: csrf_token=abc123
    
  • 适用场景:表单提交、敏感操作(如转账)。

2. 时间戳 + 超时验证

  • 原理
    • 客户端在请求中添加当前时间戳(如 timestamp=1679800000)。
    • 服务器检查时间戳是否在合理范围内(如 ±5分钟内)。
  • 增强方案:结合Token使用,避免攻击者篡改时间戳。
  • 代码示例
    // 服务端验证逻辑
    long requestTime = request.getParameter("timestamp");
    long serverTime = System.currentTimeMillis() / 1000;
    if (Math.abs(serverTime - requestTime) > 300) { // 5分钟容忍窗口
        throw new SecurityException("请求已过期");
    }
    

3. Nonce(一次性随机数)

  • 原理
    • 客户端生成唯一随机数(Nonce),随请求发送。
    • 服务器记录已使用的Nonce,拒绝重复值。
  • 优势:无需服务器生成Token,适合分布式系统。
  • 注意:需结合签名(如HMAC)防止Nonce被篡改。

4. 请求签名(如HMAC)

  • 原理
    • 客户端使用密钥对请求参数签名(如 sign=HMAC(params + timestamp, key))。
    • 服务器验证签名有效性及时间戳。
  • 适用场景:API接口、无状态服务。
  • 示例
    # 客户端生成签名
    import hmac
    params = "amount=100&timestamp=1679800000"
    sign = hmac.new(b"secret_key", params.encode(), "sha256").hexdigest()
    
    # 服务端验证
    expected_sign = hmac.new(b"secret_key", params.encode(), "sha256").hexdigest()
    if request.sign != expected_sign:
        return "签名无效"
    

5. HTTPS + 安全Cookie

  • 作用
    • HTTPS加密传输内容,防止请求被截获。
    • 设置Cookie的 SecureHttpOnlySameSite 属性,限制跨站请求。
  • 配置示例
    # Nginx配置HTTPS
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
    
    # Cookie安全属性
    Set-Cookie: session_id=xyz; Secure; HttpOnly; SameSite=Strict
    

6. 幂等性设计

  • 原理
    • 对关键操作(如支付)设计幂等接口,即使重复请求结果也一致。
    • 通过唯一交易号(idempotency_key)去重。
  • 实现
    POST /payment HTTP/1.1
    Idempotency-Key: req_12345
    

综合防御策略建议

  1. 敏感操作:使用Token + 时间戳 + 签名。
  2. API接口:Nonce + HMAC签名 + HTTPS。
  3. Web表单:CSRF Token + HTTPS。
  4. 支付场景:幂等性设计 + 双重验证(如短信验证码)。

注意事项

  • Token存储:避免将Token存储在本地存储(易被XSS攻击获取),优先使用Cookie的 HttpOnly 属性。
  • 时钟同步:时间戳方案需考虑客户端与服务端时间偏差(如NTP同步)。
  • 密钥管理:签名密钥需安全存储,避免泄露。

通过组合上述方法,可有效防御重放攻击,具体方案需根据业务场景和安全需求权衡。