security: 移除硬编码微信小程序 appId/appSecret,改为只读配置+缺失即失败
- 后端不再兜底内置 appId/appSecret,缺失时 jscode2session/手机号/支付/内容审核等接口明确拒绝(fail-closed) - 建表种子改为空值;启动自愈由「写入占位值」改为「清空历史占位值」,杜绝误用非本小程序 appId(40037 根因) - 后台/引导文案去除具体 AppID;文档补充 WX_APP_ID/WX_APP_SECRET 说明 - 新增回归护栏 wechat-appid-config-hardening.spec.ts(87 套件/636 用例全绿);HTTP 冒烟 4/4 验证缺失即失败
这个提交包含在:
@@ -0,0 +1,41 @@
|
||||
// 已读取AGENTS.md
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
/**
|
||||
* 第七十一批回归闸门:移除硬编码微信小程序 appId/appSecret,改为"只读配置 + 缺失即失败"。
|
||||
* 背景:源码/DB 内置占位凭证会被后端静默使用,导致 appId 与建模板的小程序不一致(订阅消息 40037)。
|
||||
*/
|
||||
describe('第七十一批小程序凭证去硬编码闸门', () => {
|
||||
const root = path.resolve(__dirname, '../../');
|
||||
const indexCode = fs.readFileSync(path.join(root, 'server/src/index.ts'), 'utf-8');
|
||||
const mysqlCode = fs.readFileSync(path.join(root, 'server/src/db/mysql.ts'), 'utf-8');
|
||||
const adminCode = fs.readFileSync(
|
||||
path.join(root, 'admin/arco-design-pro-vite/src/views/safety/platform-config/index.vue'),
|
||||
'utf-8'
|
||||
);
|
||||
|
||||
it('后端不再有硬编码 appId/appSecret 兜底', () => {
|
||||
expect(indexCode).not.toContain("|| 'wx0c929f7e54024e67'");
|
||||
expect(indexCode).not.toContain("|| '63a412f3f73af8e73f6923943bf9683c'");
|
||||
expect(indexCode).toContain("appId: process.env.WX_APP_ID || ''");
|
||||
expect(indexCode).toContain("appSecret: process.env.WX_APP_SECRET || ''");
|
||||
});
|
||||
|
||||
it('缺失凭证时按接口 fail-closed 并给出明确提示', () => {
|
||||
expect(indexCode).toContain('服务端未配置小程序 AppID/AppSecret,无法换取 openid');
|
||||
expect(indexCode).toContain('服务端未配置小程序 AppID(后台「微信支付商户配置」或环境变量 WX_APP_ID)');
|
||||
});
|
||||
|
||||
it('建表种子为空值,并清理历史遗留的占位凭证', () => {
|
||||
expect(mysqlCode).toContain('appId: \'\',\n appSecret: \'\',');
|
||||
// 自愈逻辑由"写入占位值"改为"清空占位值"
|
||||
expect(mysqlCode).toContain("if (curVal.appId === 'wx0c929f7e54024e67'");
|
||||
expect(mysqlCode).toContain("if (curVal.appSecret === '63a412f3f73af8e73f6923943bf9683c')");
|
||||
expect(mysqlCode).toContain('curVal.appId = \'\'');
|
||||
});
|
||||
|
||||
it('后台文案不再暴露具体 AppID', () => {
|
||||
expect(adminCode).not.toContain('wx0c929f7e54024e67');
|
||||
});
|
||||
});
|
||||
在新工单中引用
屏蔽一个用户