From a61051fa963c7cca03ab97c92ea4bd71078f6494 Mon Sep 17 00:00:00 2001 From: xcbyy <2578898740@qq.com> Date: Mon, 19 Oct 2026 13:39:04 +0800 Subject: [PATCH] =?UTF-8?q?security:=20=E4=BF=AE=E5=A4=8D=E5=85=AC?= =?UTF-8?q?=E5=BC=80=E9=85=8D=E7=BD=AE=E6=8E=A5=E5=8F=A3=E6=B3=84=E9=9C=B2?= =?UTF-8?q?=E5=AF=86=E9=92=A5=EF=BC=88map=5Flocation=5Fconfig/security=5Fw?= =?UTF-8?q?ords=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - /api/system/configs 无需登录,此前原样下发 map_location_config(腾讯位置服务 SecretKey)与 security_words(风控词库) - getPlatformConfigs 改为:排除 security_words/map_location_config,并递归剔除 secret/private/apiv3/token/pem/cert/mchid 等敏感字段 - wechat_pay_config 仍仅返回脱敏字段(mode/appId/mchIdConfigured) - 新增回归护栏 public-config-privacy.spec.ts(89 套件/644 用例全绿);冒烟 5/5 --- server/src/db/repository.ts | 18 ++++++++++++++++- server/tests/public-config-privacy.spec.ts | 23 ++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 server/tests/public-config-privacy.spec.ts diff --git a/server/src/db/repository.ts b/server/src/db/repository.ts index b2f7e0e..21a203a 100644 --- a/server/src/db/repository.ts +++ b/server/src/db/repository.ts @@ -2700,8 +2700,24 @@ export class MysqlRepository { FROM platform_configs WHERE status = 1 `); + // 移动端公开配置:严禁下发任何密钥/风控内部数据(该接口无需登录) + const PUBLIC_EXCLUDED_KEYS = new Set(['security_words', 'map_location_config']); + const SENSITIVE_FIELD = /(secret|private|apiv3|api_v3|password|passwd|token|pem|cert|mchid)/i; + const stripSensitive = (val: any): any => { + if (Array.isArray(val)) return val.map(stripSensitive); + if (val && typeof val === 'object') { + const out: { [k: string]: any } = {}; + for (const [k, v] of Object.entries(val)) { + if (SENSITIVE_FIELD.test(k)) continue; + out[k] = stripSensitive(v); + } + return out; + } + return val; + }; const result: { [key: string]: any } = {}; for (const r of rows) { + if (PUBLIC_EXCLUDED_KEYS.has(r.configKey)) continue; let val = r.valueJson; if (typeof val === 'string') { try { @@ -2715,7 +2731,7 @@ export class MysqlRepository { mchIdConfigured: Boolean(val.mchId && val.apiV3Key && val.privateKey) }; } else { - result[r.configKey] = val; + result[r.configKey] = stripSensitive(val); } } return result; diff --git a/server/tests/public-config-privacy.spec.ts b/server/tests/public-config-privacy.spec.ts new file mode 100644 index 0000000..f599d0e --- /dev/null +++ b/server/tests/public-config-privacy.spec.ts @@ -0,0 +1,23 @@ +// 已读取AGENTS.md +import * as fs from 'fs'; +import * as path from 'path'; + +/** + * 第七十三批回归闸门:移动端公开配置不得泄露密钥/风控数据。 + * 背景:/api/system/configs 无需登录,曾原样下发 map_location_config(含 SecretKey) 与 security_words(风控词库)。 + */ +describe('第七十三批公开配置隐私闸门', () => { + const root = path.resolve(__dirname, '../../'); + const repo = fs.readFileSync(path.join(root, 'server/src/db/repository.ts'), 'utf-8'); + + it('公开配置排除风控词库与地图密钥配置', () => { + expect(repo).toContain("const PUBLIC_EXCLUDED_KEYS = new Set(['security_words', 'map_location_config'])"); + expect(repo).toContain('if (PUBLIC_EXCLUDED_KEYS.has(r.configKey)) continue;'); + }); + + it('公开配置递归剔除敏感字段', () => { + expect(repo).toContain('const stripSensitive = (val: any)'); + expect(repo).toContain('if (SENSITIVE_FIELD.test(k)) continue;'); + expect(repo).toContain('result[r.configKey] = stripSensitive(val);'); + }); +});