Compare commits

...

2 Commits

Author SHA1 Message Date
192b43bc67 feat(auth): R114 默认口令 SoT 缺口注释同步(已下沉为仓内常驻门禁)
passwordPolicy.js 头注原如实登记「尚无仓内机检」覆盖默认口令清单。
本轮 R114 已把断言下沉进仓(scripts/unit_password_policy.cjs 第 [8] 段 16 项
+ scripts/unit_password_policy_mutation.cjs 3 个新变异体),并接线为
scripts/ci-gates.sh 第 25 步 ⇒ 原注释失实,就地更正为「已收口」。

同时明确机检覆盖边界:机检覆盖「本清单自身的形状与判定行为」(非空 /
双通道命中 / 非默认不误伤);「本清单 <-> database/schema.sql <-> seeder 002」
三处的跨文件同值仍靠人工核对。
2026-10-14 11:30:41 +08:00
14a110eb5f docs(auth): R113-㉔ 哈希来源注释同步(schema.sql 已统一为 bcrypt)
㉔ 采纳 bcrypt:database/schema.sql 的初始口令由 SHA256(admin) 统一为 bcrypt(admin123) ⇒ 与 seeder 002 同值同形态(两条建库路径收敛)。本文件同步两处来源注释(⛔ 未删原文,保留可追溯性):
① isDefaultAdminHash 头注 —— 哈希通道来源改为「R113 前 schema.sql 无盐 SHA256;R113 起 schema.sql 与 seeder 002 统一为同一固定盐 bcrypt」;
② KNOWN_DEFAULT_ADMIN_HASHES 来源注释 —— SHA256 项改注为「历史值保留」(旧库/旧备份仍须拦截,且非默认口令不会命中)、bcrypt 项注明「两处已收敛为同值」。

验证:node --check ✔;单测 34/34;变异 3/3;R112 驱动回归 45/45;R113 判别力自证 9/9 + 5 变异全红(仓外 .workbuddy/tmp/r113/verify_r113_changes.cjs);verify_no_secrets HIGH 0/CAND 2(零新增);verify_tautology_guard PASS;verify_constant_shape_guard PASS;三文件 CR=0。
2026-10-14 11:18:08 +08:00

View File

@@ -241,16 +241,20 @@ function requireTestPassword(appConfig) {
* ⚠️ bcrypt 的盐是**随机**的:同一口令每次哈希结果都不同 ⇒ ⛔ 不能只比对哈希字符串。 * ⚠️ bcrypt 的盐是**随机**的:同一口令每次哈希结果都不同 ⇒ ⛔ 不能只比对哈希字符串。
* 故本模块提供**两条互补通道**,由调用方 OR 合并(见 `controller/auth.js adminLogin`): * 故本模块提供**两条互补通道**,由调用方 OR 合并(见 `controller/auth.js adminLogin`):
* · 哈希通道 `isDefaultAdminHash(dbHash)` —— 覆盖「DB 里就是内置的那串哈希」 * · 哈希通道 `isDefaultAdminHash(dbHash)` —— 覆盖「DB 里就是内置的那串哈希」
* (`schema.sql` 的无盐 SHA256 + seeder 002 的固定盐 bcrypt),**与输入无关**; * (R113 前 `schema.sql` 的无盐 SHA256;R113 起 `schema.sql` 与 `seeder 002`
* 统一为**同一固定盐 bcrypt**),**与输入无关**;
* · 口令通道 `DEFAULT_ADMIN_PASSWORDS.includes(明文)` —— 覆盖「同口令、不同盐」 * · 口令通道 `DEFAULT_ADMIN_PASSWORDS.includes(明文)` —— 覆盖「同口令、不同盐」
* 的**重新播种**场景(登录成功的明文必等于该默认口令,见 `002-seed-admin.js` 的 * 的**重新播种**场景(登录成功的明文必等于该默认口令,见 `002-seed-admin.js` 的
* `ADMIN_INIT_PASSWORD` 分支会以随机盐重算哈希)。 * `ADMIN_INIT_PASSWORD` 分支会以随机盐重算哈希)。
* 二者合并即覆盖「**已知**默认口令的任意存储形态」。 * 二者合并即覆盖「**已知**默认口令的任意存储形态」。
* ⚠️ 未列入清单的默认口令仍是缺口 ⇒ 新增内置账号时**必须同步登记到下方清单** * ⚠️ 未列入清单的默认口令仍是缺口 ⇒ 新增内置账号时**必须同步登记到下方清单**
* (这是**刻意的显式维护点**,避免静默逃逸)。 * (这是**刻意的显式维护点**,避免静默逃逸)。
* ⚠️ 已知缺口(如实登记):**目前尚无仓内机检**覆盖本清单 —— 漏登记不会自动报红 * ✅ R114 已收口(本条曾登记的「尚无仓内机检」缺口):断言已**下沉进仓**为常驻门禁 ——
* (R112 的判别力自证属一次性仓外驱动,未下沉为常驻门禁)⇒ 需**人工核对** * `scripts/unit_password_policy.cjs` 第 [8] 段 + `scripts/unit_password_policy_mutation.cjs`
* 「本清单 ↔ `database/schema.sql` ↔ seeder 002」三处。 * (+4 组变异体),接线为 `scripts/ci-gates.sh` 第 **25 步**(两条 `run_gate` 均阻断)⇒
* 本清单被**清空 / 字面改写 / 判定整体禁用**时,电池即**自动报红**(判别力由变异测试自证)。
* ⚠️ 机检覆盖的是「本清单**自身的形状与判定行为**」(非空 · 双通道命中 · 非默认不误伤);
* 「本清单 ↔ `database/schema.sql` ↔ seeder 002」三处的**跨文件同值**仍靠**人工核对**。
*/ */
/** 内置默认管理员口令(**唯一真相源**;登录守卫与文档口径均以此为准) */ /** 内置默认管理员口令(**唯一真相源**;登录守卫与文档口径均以此为准) */
@@ -258,8 +262,11 @@ const DEFAULT_ADMIN_PASSWORDS = ['admin', 'admin123', 'admin123456'];
/** /**
* 已发布默认管理员凭据的**字面哈希**(固定值,可精确比对)。 * 已发布默认管理员凭据的**字面哈希**(固定值,可精确比对)。
* · `8c69…4918`:SHA256(无盐) ← `database/schema.sql` 的建库 INSERT; * · `8c69…4918`:SHA256(无盐) —— **R113 前** `database/schema.sql` 建库 INSERT 的产物;
* · `$2b$10$Nc6…co9.`:bcrypt(cost=10, 固定盐) ← `backend/database/seeders/002-seed-admin.js`。 * 自 **R113(候选㉔)** 起该文件已统一为下方 bcrypt ⇒ 本项作为**历史值保留**,
* 用于拦截仍存该哈希的旧库 / 旧备份(⛔ 不删:保留即安全 —— 非默认口令不会命中)。
* · `$2b$10$Nc6…co9.`:bcrypt(cost=10, 固定盐) —— 来源**两处已收敛为同值**:
* `database/schema.sql` 的建库 INSERT + `backend/database/seeders/002-seed-admin.js`。
*/ */
const KNOWN_DEFAULT_ADMIN_HASHES = [ const KNOWN_DEFAULT_ADMIN_HASHES = [
'8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918', '8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918',