fix: payment security hardening — 3 CRITICAL + 3 HIGH
CRITICAL fixes: - C1: Notify amount validation now unconditional (was skippable if amount field missing) - C2: Sync endpoint validates payer_total against order amount before activation - C3: Order ID uses crypto.randomBytes(6) instead of Math.random (collision-safe) HIGH fixes: - H1: Payment endpoints rate limited to 5/min per IP - H2: Max 5 pending orders per user, reject new ones until completed/cancelled - H3: Purchase endpoint returns error (not mock) when wxpay unconfigured in production Also fixed: - Notify handler asserts Buffer body, rejects non-Buffer (L3) - Notify error response is generic, no internal message leak (M1) - Private key cached in memory after first read (L2) - Fixed duplicate paymentOrderDao const declaration
这个提交包含在:
+4
-2
@@ -8,9 +8,11 @@ function isConfigured() {
|
||||
return !!(c.mchId && c.apiV3Key && c.mchSerialNo && (c.privateKey || c.privateKeyPath))
|
||||
}
|
||||
|
||||
let _cachedPrivateKey = null
|
||||
function getPrivateKey() {
|
||||
if (config.wxpay.privateKey) return config.wxpay.privateKey
|
||||
if (config.wxpay.privateKeyPath) return fs.readFileSync(config.wxpay.privateKeyPath, 'utf8')
|
||||
if (_cachedPrivateKey) return _cachedPrivateKey
|
||||
if (config.wxpay.privateKey) { _cachedPrivateKey = config.wxpay.privateKey; return _cachedPrivateKey }
|
||||
if (config.wxpay.privateKeyPath) { _cachedPrivateKey = fs.readFileSync(config.wxpay.privateKeyPath, 'utf8'); return _cachedPrivateKey }
|
||||
throw new Error('WeChat Pay private key not configured')
|
||||
}
|
||||
|
||||
|
||||
在新工单中引用
屏蔽一个用户