Files
full/.workbuddy/memory/2026-09-22.md
2026-09-22 21:15:34 +08:00

13 KiB
Raw Permalink Blame History

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-总体审计报告.mdP0/P1 风险台账 + 共性根因 + 修复优先级)、产品与服务目录.md(服务域/清单/完成度/跨域耦合/拓扑)。
  • 更新 wiki/README.md、根 README.md 的文档索引。
  • 未修改任何源码/脚本。

审计约定(本次确立,后续沿用)

  • 每篇结构:头部信息表 → 定位职责 → 代码结构与入口 → 接口清单 → 数据模型 → 核心流程(mermaid) → 审计发现(安全/正确性/未完成/健壮性) → 风险汇总表 → 修复建议(务实项)。
  • 结论必须带 文件:行号 证据;无法确认标【信息不足】。
  • 修复建议只给最小直接动作,禁止统一框架/抽象层/DTO/VO/DDD/CQRS/拆微服务边界一类建议。

关键结论P0 摘要,供后续跟踪)

  • 认证passport 与 mall 的验证码登录/注册不校验验证码passport Forget.Reset 凭 identity 即可改密且写未加盐 MD5mgt 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.gobase 多数模块、wallet、social 三服务零单测。

方法备注

  • 本机 bash shim 缺 dirnamePATH 报错但不影响),需 export PATH="/usr/bin:/bin:$PATH" 后执行 find/grep/lsPowerShell 输出未被捕获,改用 Bash/Glob/Grep。
  • 大批量逐服务审计采用并行子代理general-purpose分域产出子代理默认模型触发 429 时切换 model: "lite" 可用;范例先由主代理写 docs/logs.md 固化为模板。
  • 子代理无法 SendMessage非 team 会话),改为在回复中汇报。

passport 密码哈希整改(按 docs/passport.md 建议 2、3

改动4 个文件,未触碰其他模块)

  • internal/logic/forget/reset.goutils.Md5(pwd)bcrypt.GenerateFromPassword(pwd+新salt, DefaultCost),并在同一条 Updates(map) 中同步写 passwordsalt。修复 P4重置后与登录校验不兼容 + 未加盐 MD5
  • register/do.go:30account/set_password.go:35models/query.go:21bcrypt.MinCost(4) → DefaultCost(10)。修复 P5。

项目约定(重要,后续复用)

  • passport 密码存储约定:hash = bcrypt(password + salt)saltutils.UUID() 独立存列,登录用 bcrypt.CompareHashAndPassword(hash, password+pa.Salt) 校验。任何改密路径必须同时更新 passwordsalt
  • 编译校验方式workspace 模式下 go build 会因 genproto 拆包报 ambiguous import环境问题非代码问题GOWORK=off go build ./... 在模块目录内校验。Go 在 D:\devapps\Go-1271\binSDK 在 D:\work\bsm-sdk\core
  • 复核命令:gofmt -lGOWORK=off go build ./...GOWORK=off go vet ./internal/...

遗留passport 的验证码校验P1/P2、找回密码身份校验P3、Token 前缀P6、KYCP7、日志 PIIP9、事务/错误处理P10、单测仍待处理。已在 docs/passport.md 新增"## 9. 整改记录"保留审计与整改的对应关系。

按审计报告全量整改 P0/P1P0+P1 + 各服务报告「高」项)

范围口径(本次确立):用户说"处理所有 P0/P1",实际执行口径 = wiki/audit-2026-09-22-总体审计报告.md 的 P0(S1S30)/P1(H1H20) 并集docs/<服务>.md「风险汇总」表中标注为「高」的行(约 100 项)。中/低项未处理。

关键约束(重要,后续复用)

  • 本机没有 protocproto/*.protopb/*.go 一律不能改。所有修复必须在现有接口/字段内完成;必须新增请求字段才能修的,改为"拒绝该操作 + 说明"。本次全程未改任何 proto/pbgit status -- '*/proto/*' '*/pb/*' 为空)。
  • 所有密码/口令摘要统一 golang.org/x/crypto/bcryptDefaultCost)。注意 bcrypt 是单向哈希,可逆加密(如 cloud 私人资料内容)用 SDK 的 crypto/aes
  • 注释一律中文。禁止过度设计(新框架/抽象层/DTO/VO/事件总线/服务网格/拆服务边界/跨库改 RPC

主要整改内容(按域)

  • walletPayment.Callback 不再接受调用方自证成功(只允许取消/失败,条件更新+幂等);WxCallback 落地结算(按 out_trade_no 反查 + 金额核对 + 事务内入账写流水);余额/提现改条件更新 WHERE balance >= ? 防双花、同事务写 wallet_record 并补 Ymd/Ym;支付密码改 bcrypt 且禁止无旧密码覆盖alipay Body/ctx 初始化修 panicFindWalletRecords 回写 tx + 独立 Count三个 etc yaml 重写(字段名 + 凭据改 ${ENV} 占位,os.ExpandEnv 会展开)。
  • passport/SMS/Code/{phone} 真实校验(校验成功删 key+ 找回密码一次性票据(/PASSPORT/FORGET/RESET/{identity}TTL 10min改密后删Token key 统一用 vars.TokenPrefix
  • mgtAppKey 登录改 bcrypt 比对;去 root/123456,改 BSM_MGT_ROOT_PASSWORD 环境变量。
  • mall员工验证码登录补校验店铺凭据 5 接口补 Mall_Admin + 店铺归属12 处写操作补店铺归属;成本价对匿名/非本店隐藏12 个占位接口改 ErrUnimplemented
  • orderSimulate* 加 dev 开关(非 dev 拒绝)+ 去硬编码金额;OrderApprove 补鉴权/状态校验/归属;优惠券改减法 + 归属/状态/有效期;扣库存改原子条件更新查 RowsAffectedstore_id 取值修正;取消订单事务内回补库存;购物车/订单详情/地址补归属;购物车不下发成本价。
  • market审核/开号/删号补鉴权;以 auth.Identity 取代请求 identityData 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 BYclause.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/ecmalldefault_prod.yaml/default_test.yamlJWT/session 密钥拒绝公开默认值(含 SDK 的 Cblocksmesh2022C必须走环境变量gateway 404 改 WithRoutingErrorHandler 标记"路由未命中"才回退 Gin业务 NotFound 原样透出;打开 with.Databases(..., IsAutoMigrate: true) 让聚合建表;build-all-linux.sh 覆盖 pkgs/*
  • scripts/workspaceapi-docgen 6 处依赖对齐 + 纳入 go.workverify-workspace.* 纳入 scripts/、空模块列表报错、加 SDK 缺失前置检查;新增 .gitattributesREADME 补"本地开发前提"。

已知遗留(需产品/契约决策,未擅自改)

  • 聚合播种:InitData/InitRootUsermodule/**/internal/**Go internalpkgs 不可导入),聚合只能建表不能播种;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.gocheckPwdAndStatus 仍保留 MD5 向后兼容分支crypto/md5 + encoding/hex)。与"所有加密统一 bcrypt"冲突,已删除该分支(相应 import 一并移除)。副作用:库中历史 MD5 口令无法再登录,需走重置流程——与 passport 的历史数据处理口径一致。
  2. module/ec/mall/internal/logic/freight/deny_region_remove.goM12 的 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_JwtSecretKey16/24/32 字节私有值)、BSM_SECRET_KEYsession HMACBSM_MGT_SECRET_KEYBSM_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.gointegration 构建标签,不在默认测试范围)。