Hacktoberfest 2026 : les issues que les mainteneurs ont marquées pour octobre, ouvertes et accessibles aux débutants. Parcourir les issues Hacktoberfest

【安全】WxPayValidator 未校验微信支付 V3 应答时间戳(Wechatpay-Timestamp),缺少重放攻击防护

Fermée
#4,133 2 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

Personne n'a encore pris cette issue.

Évaluation

Difficulté
3/5
Temps estimé
1-2 jours
Accessibilité débutants
68/100
Type d'issue
Bug
Clarté
Clairement spécifiée
Activité
Active
Stack technique
java

Piste de recherche

Start with weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/auth/WxPayValidator.java, especially validate(CloseableHttpResponse), and trace its call from SignatureExec.executeWithSignature. Verify the timestamp freshness behavior against the stated five-minute requirement and check the handling of non-JSON 2xx responses; the work is done when expired responses are rejected while valid signed responses remain accepted.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

【微信支付 V3】WxPayValidator 未校验应答时间戳,缺少重放攻击防护(Wechatpay-Timestamp 未做新鲜度校验)

漏洞类型:重放攻击防护缺失
影响组件:weixin-java-pay / WxPayValidator
风险场景:链路窃听、中间人重放合法应答

1. 环境

项目 内容
SDK 版本 binarywang/WxJava develop 分支(4.8.x 范围内),含 WxPayValidator 的所有已发布 4.x 版本均受影响
模块 weixin-java-pay
Java 版本 JDK 8+
接入方式 微信支付 V3(WxPayService + AutoUpdateCertificatesVerifier / CertificatesVerifier,WxPayV3HttpClientBuilder 构建的 CloseableHttpClient)

2. 复现步骤

  1. 按官方方式初始化微信支付 V3 的 WxPayService,使用 WxPayV3HttpClientBuilder 拿到 HttpClient(内部通过 SignatureExec 对 2xx 应答做 WxPayValidator.validate)。
  2. 调用任意 V3 接口(如“查询订单”),正常拿到应答。
  3. 攻击者截获该次应答,包含:
    • Wechatpay-Timestamp
    • Wechatpay-Nonce
    • Wechatpay-Signature
    • Wechatpay-Serial
    • JSON body
  4. 在数分钟、数小时或任意时间后,将此应答原样重放给调用方,或由链路上的中间人重放。

3. 期望行为

依据微信支付 V3 签名验证规范,商户侧应校验 Wechatpay-Timestamp 与本地时间之差不超过 5 分钟;超时的应答应判定为验签失败,以提供重放攻击防护。

4. 实际行为

WxPayValidator.validate(...) 只校验四个头部是否存在,并做密码学验签,从不校验时间戳新鲜度。

方法内明确留有:

// todo: check timestamp

但未实现。

因此,重放的旧应答仍被判定为验签通过,SignatureExec 不会抛出异常,调用方拿到被重放的数据。

5. 根因分析

  • 文件:weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/auth/WxPayValidator.java
  • 方法:validate(CloseableHttpResponse response)(约第 27–34 行)
  • 相关代码:
// todo: check timestamp
if (timestamp == null || nonce == null || serialNo == null || sign == null) {
  return false;
}
String message = buildMessage(response);
return verifier.verify(serialNo.getValue(), message.getBytes(StandardCharsets.UTF_8), sign.getValue());
  • 原因:
    • verifier.verify(...) 仅使用平台证书对 timestamp\nnonce\nbody\n 做 RSA 验签。
    • 时间戳本身被当作“参与签名的字符串”,而不是“需校验的时间量”。
    • 缺失类似 |当前秒 - Long.parseLong(timestamp)| <= 300 的新鲜度判断,导致重放攻击防护缺位。

6. 影响

在存在链路窃听或中间人的场景下,合法应答可被重放并被判为有效,违反微信支付 V3 防重放要求。

同时,validate 对 Content-Type 非 application/json 的 2xx 应答直接 return true 跳过验签(同方法首行),进一步放大风险。

7. 建议修复方向

在 validate 中补充时间戳新鲜度校验,例如:

long wechatTimestamp = Long.parseLong(timestamp.getValue());
long diff = Math.abs(System.currentTimeMillis() / 1000 - wechatTimestamp);
if (diff > 300) {
  log.warn("微信支付应答时间戳超时,疑似重放攻击:{} 秒", diff);
  return false;
}

并建议将首行的“非 JSON 直接 return true”改为:

  • 对未知或非 JSON 的 2xx 应答默认拒绝;或
  • 至少记录告警,避免绕过验签。

8. 参考

  • 微信支付 V3 签名验证规范:应答/回调需校验 Wechatpay-Timestamp 与本地时间差不超过 5 分钟,防止重放。
  • 相关代码路径:SignatureExec.executeWithSignature(...) -> validator.validate(response)。
Langage dominant
Java
Étoiles
33.1k
Forks
9.1k
Merge moyen
3 j 11 h
PR mergées (30 j)
10

Préparer son environnement

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de binarywang/WxJava

Toutes les issues de binarywang/WxJava

Issues similaires

Plus d'issues Java

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.