Files
competition-website/config
qubiaobiao 89b9b2b0da security(config): 移除内置 JWT 密钥明文兜底,收敛到唯一解析入口(R105-D1)
问题(R104 卫生清理 H2 分类的唯二受版本控制命中):
  config.default.js 原为
      const DEFAULT_JWT_SECRET = 'competition_jwt_secret_key_2026_br!cs';
      secret: process.env.JWT_SECRET || DEFAULT_JWT_SECRET
  该常量为**已入库、任何人可读**的明文,且与 scripts/.creds.local.json 的
  jwt_fallback_secret 同值 ⇒ 等价于「JWT 签名密钥公开 ⇒ 任意人可伪造 token
  冒充任意身份」。它与仓库既有纪律(_creds.py / _db.cjs / 本文件:459 对
  DB_PASSWORD 的「缺失即阻断」)不一致 —— 同族问题各自实现必然漂移。

修法:
  · config/config.default.js
      - 删除 DEFAULT_JWT_SECRET 常量与 `||` 兜底,改调唯一解析入口;
      - 生产安全守卫中同步移除 `jwt.secret === DEFAULT_JWT_SECRET` 比对分支
        (不再存在可比的兜底值;缺失时解析期即抛错)。
  · 新增 scripts/_secret.cjs(与 _db.cjs / _creds.py 同一纪律)
      ① env JWT_SECRET → ② scripts/.creds.local.json:jwt_fallback_secret
      → ③ 明确失败(⛔ 刻意不提供明文兜底)

行为等价性:生产经 systemd EnvironmentFile、本地经 loadDeployEnv 从
deploy/.env.production 注入 JWT_SECRET,正常运行路径逐字不变;仅消除了
「密钥缺失时静默使用公开值」这一分支。

验证:
  · 后端真实重启 ⇒ 配置加载成功,生效 jwt.secret 指纹与注入值一致;
  · 端到端判别力(本地 7001 与生产 8023 各一次):新密钥签发 ⇒ 200,
    旧密钥签发 ⇒ 401(auth.js jwt.verify 分支);
  · scripts/verify_no_secrets.py:HIGH 0,判别力自证 17/17;
  · scripts/verify_script_health.py:H1–H4 PASS。
2026-10-12 10:26:03 +08:00
..
2026-08-17 12:25:42 +08:00