13 KiB
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;mgtAppKey登录明文比对密码列;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 会话),改为在回复中汇报。
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;Data5 接口改ErrUnimplemented;登录签发改 SDKtoken.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按用户唯一;容量配额落地上限校验;initialORDER 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):
module/base/mgt/internal/logic/pub/login.go:checkPwdAndStatus仍保留 MD5 向后兼容分支(crypto/md5+encoding/hex)。与"所有加密统一 bcrypt"冲突,已删除该分支(相应 import 一并移除)。副作用:库中历史 MD5 口令无法再登录,需走重置流程——与 passport 的历史数据处理口径一致。module/ec/mall/internal/logic/freight/deny_region_remove.go:M12的 9 个运费接口中唯一被漏掉的一个,仍是// TODO+ 返回OK。已改errcode.ErrUnimplemented(去掉timeimport)。module/ec/mall/internal/logic/store/set_setting.go:直接凭请求参数id/identity更新mall_store,无店铺归属校验且不检查RowsAffected→ 可改他人店铺设置且静默成功。已改为以 token 中store_identity为准 + 检查RowsAffected(与同目录set_payment.go的既有范式一致)。module/base/cloud/internal/logic/private/crypto.go:密钥未配置时回退到 SDK 公开默认密钥(env.NewEnv().JwtSecretKey),等同于假加密。已改为只读BSM_CloudPrivateKey,未配置或 <16 字节直接报错并记日志。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 构建标签,不在默认测试范围)。