Files
full/.workbuddy/memory/2026-09-22.md

90 lines
13 KiB
Markdown
Raw Normal View History

2026-09-22 18:53:53 +08:00
# 2026-09-22 工作日志
## 全仓逐微服务代码审计(第二轮,业务实现层)
**任务**:重新分析并审计 BSM Infra Full 全部代码,按微服务名称输出 md 审计文档到 `docs/`;产品类文档放 `wiki/`;明确要求**不得提出过度设计/过度封装建议**。
**产出**
- `docs/` 新增 22 篇:18 个业务服务 + `pkgs-all.md`/`pkgs-ecmall.md`/`workspace-and-scripts.md` + `README.md` 索引。
- `wiki/` 新增产品级文档 2 篇:`audit-2026-09-22-总体审计报告.md`(P0/P1 风险台账 + 共性根因 + 修复优先级)、`产品与服务目录.md`(服务域/清单/完成度/跨域耦合/拓扑)。
- 更新 `wiki/README.md`、根 `README.md` 的文档索引。
- 未修改任何源码/脚本。
**审计约定(本次确立,后续沿用)**
- 每篇结构:头部信息表 → 定位职责 → 代码结构与入口 → 接口清单 → 数据模型 → 核心流程(mermaid) → 审计发现(安全/正确性/未完成/健壮性) → 风险汇总表 → 修复建议(务实项)。
- 结论必须带 `文件:行号` 证据;无法确认标【信息不足】。
- 修复建议只给最小直接动作,禁止统一框架/抽象层/DTO/VO/DDD/CQRS/拆微服务边界一类建议。
**关键结论(P0 摘要,供后续跟踪)**
- 认证:passport 与 mall 的验证码登录/注册**不校验验证码**;passport `Forget.Reset` 凭 identity 即可改密且写未加盐 MD5;mgt `AppKey` 登录明文比对密码列;mgt dev 注入 `root/123456`。
- 资金:wallet 支付回调**不验签**、提现只校验不扣减无幂等、余额扣减读后写;order 模拟支付/发货生产可达、`OrderApprove` 无鉴权、优惠券金额**做加法**致应付变高、扣库存不检查 RowsAffected。
- 越权:address/cms/group/relation/feed/mall/market/feedback 共 9 个模块存在"只校验登录、不校验归属/角色"。
- 上线阻断:pkgs 无 prod 配置、JWT/session 密钥默认值恰 32 字节可用、gateway 404 与业务 NotFound 无法区分;`scripts/api-docgen` 无法构建。
- 静默故障:多处引用不存在的列(`relation_id`/`creator_id`/`createor_id`/`enabled`)与命名返回值 `reply` 未赋值。
- 测试:全仓仅 21 个 `*_test.go`,base 多数模块、wallet、social 三服务零单测。
**方法备注**
- 本机 bash shim 缺 `dirname`(PATH 报错但不影响),需 `export PATH="/usr/bin:/bin:$PATH"` 后执行 `find`/`grep`/`ls`;PowerShell 输出未被捕获,改用 Bash/Glob/Grep。
- 大批量逐服务审计采用并行子代理(general-purpose)分域产出,子代理默认模型触发 429 时切换 `model: "lite"` 可用;范例先由主代理写 `docs/logs.md` 固化为模板。
- 子代理无法 SendMessage(非 team 会话),改为在回复中汇报。
2026-09-22 21:15:34 +08:00
## passport 密码哈希整改(按 docs/passport.md 建议 2、3)
**改动(4 个文件,未触碰其他模块)**
- `internal/logic/forget/reset.go`:`utils.Md5(pwd)` → `bcrypt.GenerateFromPassword(pwd+新salt, DefaultCost)`,并在同一条 `Updates(map)` 中同步写 `password` 与 `salt`。修复 P4(重置后与登录校验不兼容 + 未加盐 MD5)。
- `register/do.go:30`、`account/set_password.go:35`、`models/query.go:21`:`bcrypt.MinCost`(4) → `DefaultCost`(10)。修复 P5。
**项目约定(重要,后续复用)**
- passport 密码存储约定:`hash = bcrypt(password + salt)`,`salt` 为 `utils.UUID()` 独立存列,登录用 `bcrypt.CompareHashAndPassword(hash, password+pa.Salt)` 校验。任何改密路径必须同时更新 `password` 与 `salt`。
- 编译校验方式:workspace 模式下 `go build` 会因 genproto 拆包报 ambiguous import(环境问题,非代码问题);**用 `GOWORK=off go build ./...`** 在模块目录内校验。Go 在 `D:\devapps\Go-1271\bin`;SDK 在 `D:\work\bsm-sdk\core`。
- 复核命令:`gofmt -l`、`GOWORK=off go build ./...`、`GOWORK=off go vet ./internal/...`。
**遗留**:passport 的验证码校验(P1/P2)、找回密码身份校验(P3)、Token 前缀(P6)、KYC(P7)、日志 PII(P9)、事务/错误处理(P10)、单测仍待处理。已在 docs/passport.md 新增"## 9. 整改记录"保留审计与整改的对应关系。
## 按审计报告全量整改 P0/P1(P0+P1 + 各服务报告「高」项)
**范围口径(本次确立)**:用户说"处理所有 P0/P1",实际执行口径 = `wiki/audit-2026-09-22-总体审计报告.md` 的 P0(S1–S30)/P1(H1–H20) **并集** 各 `docs/<服务>.md`「风险汇总」表中标注为「高」的行(约 100 项)。中/低项未处理。
**关键约束(重要,后续复用)**
- **本机没有 protoc**,`proto/*.proto` 与 `pb/*.go` 一律不能改。所有修复必须在现有接口/字段内完成;必须新增请求字段才能修的,改为"拒绝该操作 + 说明"。本次全程未改任何 proto/pb(`git status -- '*/proto/*' '*/pb/*'` 为空)。
- 所有密码/口令摘要统一 `golang.org/x/crypto/bcrypt`(`DefaultCost`)。**注意 bcrypt 是单向哈希,可逆加密(如 cloud 私人资料内容)用 SDK 的 `crypto/aes`**。
- 注释一律中文。禁止过度设计(新框架/抽象层/DTO/VO/事件总线/服务网格/拆服务边界/跨库改 RPC)。
**主要整改内容(按域)**
- wallet:`Payment.Callback` 不再接受调用方自证成功(只允许取消/失败,条件更新+幂等);`WxCallback` 落地结算(按 out_trade_no 反查 + 金额核对 + 事务内入账写流水);余额/提现改条件更新 `WHERE balance >= ?` 防双花、同事务写 `wallet_record` 并补 `Ymd/Ym`;支付密码改 bcrypt 且禁止无旧密码覆盖;alipay Body/ctx 初始化修 panic;`FindWalletRecords` 回写 tx + 独立 Count;三个 etc yaml 重写(字段名 + 凭据改 `${ENV}` 占位,`os.ExpandEnv` 会展开)。
- passport:`/SMS/Code/{phone}` 真实校验(校验成功删 key)+ 找回密码一次性票据(`/PASSPORT/FORGET/RESET/{identity}`,TTL 10min,改密后删);Token key 统一用 `vars.TokenPrefix`。
- mgt:AppKey 登录改 bcrypt 比对;去 `root/123456`,改 `BSM_MGT_ROOT_PASSWORD` 环境变量。
- mall:员工验证码登录补校验;店铺凭据 5 接口补 `Mall_Admin` + 店铺归属;12 处写操作补店铺归属;成本价对匿名/非本店隐藏;12 个占位接口改 `ErrUnimplemented`。
- order:`Simulate*` 加 dev 开关(非 dev 拒绝)+ 去硬编码金额;`OrderApprove` 补鉴权/状态校验/归属;优惠券改减法 + 归属/状态/有效期;扣库存改原子条件更新查 `RowsAffected`;`store_id` 取值修正;取消订单事务内回补库存;购物车/订单详情/地址补归属;购物车不下发成本价。
- market:审核/开号/删号补鉴权;以 `auth.Identity` 取代请求 identity;`Data` 5 接口改 `ErrUnimplemented`;登录签发改 SDK `token.New(...).GenerateJwt` 与校验格式一致;分页 Offset 归一化 + 独立 Count。
- address/cms/group/relation/feed:批量补归属与角色校验、修不存在列名(`relation_id`/`creator_id`/`creator_id`/`feed_tags.identity`)、修 panic(空指针/类型断言/nil error 解引用)、修分页、实现 `DeleteComment`、补 tags/attachs 回填、改 `ErrUnimplemented`。
- cloud/initial/fts:私人资料改服务端 AES 加解密(密钥走 `BSM_CloudPrivateKey`,不再用客户端 key);分享建前校验资源归属;根目录 `*ParentID` 判空;`key_identifier` 按用户唯一;容量配额落地上限校验;initial `ORDER BY` 改 `clause.OrderBy` 参数化、版本改分段比较、`areas_cache` 列名与错误处理、匿名白名单口径;fts bucket 白名单 + `safeJoin` 防路径穿越、落库失败清理已落盘文件、路由前缀与单测统一。
- sender/feedback/logs:腾讯云短信空实现改显式"未实现"错误 + 今日限额 `Incr` 生效 + `SetNX` 返回值检查(不覆盖已有码)+ Verify 成功才删 key 且失败 5 次作废 + 黑名单读配置 + `Code` 配置非空校验 + provider 键口径统一;feedback 补身份与归属校验、PII 掩码、不再改写 identity、附件补 identity、主表+附件同事务;logs 业务接口移出匿名组、键名/类型断言/分页/IP 过滤修正。
- pkgs/all + pkgs/ecmall:补 `default_prod.yaml`/`default_test.yaml`;JWT/session 密钥拒绝公开默认值(含 SDK 的 `Cblocksmesh2022C`)必须走环境变量;gateway 404 改 `WithRoutingErrorHandler` 标记"路由未命中"才回退 Gin,业务 NotFound 原样透出;打开 `with.Databases(..., IsAutoMigrate: true)` 让聚合建表;`build-all-linux.sh` 覆盖 `pkgs/*`。
- scripts/workspace:api-docgen 6 处依赖对齐 + 纳入 `go.work`;`verify-workspace.*` 纳入 `scripts/`、空模块列表报错、加 SDK 缺失前置检查;新增 `.gitattributes`;README 补"本地开发前提"。
**已知遗留(需产品/契约决策,未擅自改)**
- 聚合播种:`InitData`/`InitRootUser` 在 `module/**/internal/**`(Go internal,pkgs 不可导入),聚合只能建表不能播种;`mgt/address/market/order` 的表由各自 `models.New()` 迁移,聚合不可达。
- social 三服务已补 `service.Expose` + gateway 接线(Mux 不再恒 nil),但**未加入 `pkgs/all` 的服务注册表**(涉及"哪些服务在聚合进程里跑"的部署决策与各服务配置段接线)。
- 无法在现有契约内完成:wallet 支付密码"旧密码校验"(需新增 proto 字段,现改为禁止无旧密码覆盖)、feed/cms 互动去重(需新增记录表)、mall `Licensing` 许可校验(无数据源)、order 优惠券使用门槛(字段无写入点)、sender 腾讯云真实发送(proto 无 `SmsSdkAppId` 与有序模板参数)。
- `verify-workspace.sh` 仍会失败,根因是**本机既有的 genproto ambiguous import**(工作区级 MVS 选中 2019 老 genproto),与本次改动无关;未做掩盖。
- `pkgs/*/etc/default_dev.yaml` 里仍有硬编码真实库口令 `Weidong1214`(不在清单内,未动)。
**复核口径**:全仓 1307 文件、20 个 Go module,逐个 `GOWORK=off go build ./...` + `go vet ./...` + `gofmt -l` 全部通过;pkgs/all、pkgs/ecmall 既有单测通过;fts 路由单测已由红转绿。
## 终检补漏:复核中又发现并修掉的 5 处
主代理逐条复核子代理产出时,发现以下**首轮遗漏/未彻底**的问题并已修复(均已通过 build/vet/gofmt):
1. `module/base/mgt/internal/logic/pub/login.go`:`checkPwdAndStatus` 仍保留 **MD5 向后兼容分支**(`crypto/md5` + `encoding/hex`)。与"所有加密统一 bcrypt"冲突,已删除该分支(相应 import 一并移除)。**副作用**:库中历史 MD5 口令无法再登录,需走重置流程——与 passport 的历史数据处理口径一致。
2. `module/ec/mall/internal/logic/freight/deny_region_remove.go`:`M12` 的 9 个运费接口中**唯一被漏掉**的一个,仍是 `// TODO` + 返回 `OK`。已改 `errcode.ErrUnimplemented`(去掉 `time` import)。
3. `module/ec/mall/internal/logic/store/set_setting.go`:直接凭**请求参数** `id/identity` 更新 `mall_store`,无店铺归属校验且不检查 `RowsAffected` → 可改他人店铺设置且静默成功。已改为以 token 中 `store_identity` 为准 + 检查 `RowsAffected`(与同目录 `set_payment.go` 的既有范式一致)。
4. `module/base/cloud/internal/logic/private/crypto.go`:密钥未配置时**回退到 SDK 公开默认密钥**(`env.NewEnv().JwtSecretKey`),等同于假加密。已改为只读 `BSM_CloudPrivateKey`,未配置或 <16 字节直接报错并记日志。
5. `module/base/cms/internal/logic/pages/*`:`C1` 只修了 `post` 系列;`CmsPages`(单页文章)模型**只有 `types.Std_IICUDS` + 站点/内容字段,无任何归属列**,现有表结构下无法做归属校验。已在 `docs/cms.md` 明确标注为**表结构限制**,未擅自改表。
**审计文档回写(重要约定)**:本轮为 21 篇 `docs/*.md` **各追加「整改记录(2026-09-22)」章节**(编号/级别/问题/处理结果四列表 + 「未纳入本轮范围」说明),并在 `docs/README.md` 加「整改进度」段、`wiki/audit-2026-09-22-总体审计报告.md` 加「九、整改结果」段(含部署前置环境变量表)。**口径**:文档表格描述的是"审计当时"状态,当前有效状态看「整改记录」章节。
**部署前置变量(整改后必须注入,否则拒绝启动或明确报错)**:`BSM_JwtSecretKey`(16/24/32 字节私有值)、`BSM_SECRET_KEY`(session HMAC)、`BSM_MGT_SECRET_KEY`、`BSM_CloudPrivateKey`(≥16 字节)、`BSM_MGT_ROOT_PASSWORD`。仓库内 `Weidong1214` / `123456` / `Cblocksmesh2022C` 已全量清除。
**仍未处理(最终口径)**:各报告中「中/低」项;`social` 三服务已补 `service.Expose` + gateway 接线但**未纳入 `pkgs/all` 服务注册表**(属部署决策);feed/cms 互动去重(需新增记录表,属契约外);`mall.Licensing` 许可证校验(无数据源);`cms_pages` 归属(需加列);`wallet` 改支付密码校验旧密码(需新增 proto 字段,现改为禁止覆盖);全仓单测覆盖仍然薄弱(sender 的 `test/grpc/*_test.go` 带 `integration` 构建标签,不在默认测试范围)。