From 9f5dd9528986ffe38ca29d859c084240c3f57828 Mon Sep 17 00:00:00 2001 From: yuetsh <517252939@qq.com> Date: Thu, 6 Aug 2026 20:24:01 -0600 Subject: [PATCH] =?UTF-8?q?docs:=20raw=5Fpassword=20=E4=BF=9D=E7=95=99?= =?UTF-8?q?=E5=86=B3=E7=AD=96=E5=8F=8A=E5=85=B6=E5=AF=B9=207.1=20=E7=BB=93?= =?UTF-8?q?=E8=AE=BA=E7=9A=84=E5=BD=B1=E5=93=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit user.raw_password 明文列是有意的运维需求(教师查学生密码),决定保留。 据此如实收窄 7.1 的结论:argon2id 升级不防"数据库泄露",只解决 pbkdf2 的 CPU 开销和脱离 Django 哈希格式,不得描述为"提升密码安全性"。 附一条未采纳的备选(应用层可逆加密)供日后备查。 Co-Authored-By: Claude Opus 5 --- .../2026-08-06-bun-backend-rewrite-design.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/docs/specs/2026-08-06-bun-backend-rewrite-design.md b/docs/specs/2026-08-06-bun-backend-rewrite-design.md index c800a9e..cb0dda8 100644 --- a/docs/specs/2026-08-06-bun-backend-rewrite-design.md +++ b/docs/specs/2026-08-06-bun-backend-rewrite-design.md @@ -154,6 +154,21 @@ argon2id : true 耗时 88 ms 1. 登录必须使用 `node:crypto` 的**异步** `pbkdf2`(走 libuv 线程池),不得使用 `pbkdf2Sync`。 2. 验证成功后立即将该用户哈希升级为 argon2id(`Bun.password`),一学期后存量自然清空。 +#### 7.1.1 `raw_password` 明文列保留(已决策) + +生产库 `user` 表有一列 `raw_password character varying(20)`(`docs/specs/schema.sql:939`),存学生明文密码。 + +**决策:保留。** 这是有意的运维需求——学生忘记密码是高频事件,教师需要能直接查到并告知,走"重置密码"流程在机房环境里成本过高。新后端照样维护这一列。 + +**对本节结论的影响,须如实记录:** 既然明文与哈希同表共存,第 2 条的 argon2id 升级**不构成对"数据库泄露"这一威胁的防护**——拿到库的人不需要破哈希。该升级实际只解决两件事: + +- 摆脱 pbkdf2 每次登录 95ms 的 CPU 开销(argon2id 88ms 但只在升级那一次,之后走更快路径) +- 不再依赖 Django 特定的哈希格式,新后端自成一体 + +不要在任何地方把它描述成"提升了密码安全性"。真实的安全边界由 `raw_password` 决定,不由哈希算法决定。 + +**若日后想在不改变教师查密码这一工作流的前提下收紧**(本次未采纳,仅备查):把 `raw_password` 改为用一把存在环境变量/密钥文件里、**不在数据库内**的密钥做可逆加密。教师查询走应用层解密,体验不变;而一份裸的数据库备份泄露时不再直接暴露明文。改动量约为一个加解密工具函数 + 一次存量数据迁移。 + ### 7.2 tree-sitter 迁移(`docs/spikes/ast-spike.ts`) 复刻 `ast_checker/mappings/c.py` 的映射表,在 Bun 中用 `web-tree-sitter` 解析 C 代码: @@ -227,7 +242,9 @@ jieba.loadDict(Buffer.from("两个整数 9999\n")) 盘点中发现的、明确不应带进新后端的实现: - **`SessionRecordMiddleware`(`account/middleware.py:22-33`)**:每个已登录请求都写一遍 session(user_agent / ip / last_activity),遇到新 session key 还额外触发一次 `request.user.save()` —— 即每请求一次数据库写。这是"Django 太慢"的实际来源之一。新后端的会话信息留在 Redis,不落库。 -- **`User.session_keys`**:只写不读的死字段,随 `/api/sessions` 端点一并砍掉。 +- **`User.session_keys`**:只写不读的死字段,随 `/api/sessions` 端点一并砍掉。(已由 `schema.sql:938` 确认该列存在。) + +反过来,**必须复刻**的一项:`user.raw_password`(`schema.sql:939`)保留,见 7.1.1。 ## 9. 判题链路