Add static security/quality audit reports for all 18 Go service modules under module/, plus a consolidated index (docs/audit/README.md) with per-module statistics, top risks, cross-module systemic defects and a phased TODO list (T1-T19). No production code is modified.
165 lines
20 KiB
Markdown
165 lines
20 KiB
Markdown
# module/ 全模块审计索引
|
||
|
||
> 状态:生成中(各模块审计文件完成后由主流程回填统计表与汇总 TODO)
|
||
|
||
## 审计范围
|
||
|
||
- 审计对象:`module/` 下全部 **18 个含 `go.mod` 的独立服务模块**(`go.work` 成员)。
|
||
- 每个模块由独立审计 agent 完成,产出 `docs/audit/module-<路径>.md`。
|
||
- 未纳入审计(无 Go 代码,不属于运行时服务):
|
||
- `module/ec/supply`:仅 1 个 `README.md`,无 `go.mod`。
|
||
- `module/finance/bill`:空目录。
|
||
- `module/finance/loan`:空目录。
|
||
|
||
## 审计维度
|
||
|
||
安全(鉴权/越权/注入/密钥/隐私)、正确性(错误处理/事务/并发/状态机/精度)、性能(N+1/索引/分页/缓存)、可维护性(重复/分层/TODO/空实现)、健壮性与可观测性(超时/重试/迁移耦合/日志/配置)、测试覆盖。
|
||
|
||
## 问题级别定义
|
||
|
||
| 级别 | 含义 |
|
||
| --- | --- |
|
||
| P0 | 可被利用的安全漏洞 / 必然导致数据损坏或资金损失 |
|
||
| P1 | 高概率线上故障、越权、性能瓶颈 |
|
||
| P2 | 可维护性、健壮性、可观测性缺陷 |
|
||
| P3 | 风格、文档、一致性改进 |
|
||
|
||
## 模块审计文件
|
||
|
||
| 模块 | 审计文件 | P0 | P1 | P2 | P3 | 合计 |
|
||
| --- | --- | ---: | ---: | ---: | ---: | ---: |
|
||
| `base/ads` | [module-base-ads.md](module-base-ads.md) | 0 | 3 | 11 | 7 | 21 |
|
||
| `base/cloud` | [module-base-cloud.md](module-base-cloud.md) | 5 | 15 | 14 | 5 | 39 |
|
||
| `base/cms` | [module-base-cms.md](module-base-cms.md) | 1 | 11 | 16 | 5 | 33 |
|
||
| `base/feedback` | [module-base-feedback.md](module-base-feedback.md) | 3 | 8 | 15 | 2 | 28 |
|
||
| `base/fts` | [module-base-fts.md](module-base-fts.md) | 2 | 5 | 10 | 7 | 24 |
|
||
| `base/initial` | [module-base-initial.md](module-base-initial.md) | 0 | 8 | 6 | 8 | 22 |
|
||
| `base/logs` | [module-base-logs.md](module-base-logs.md) | 2 | 13 | 6 | 5 | 26 |
|
||
| `base/mgt` | [module-base-mgt.md](module-base-mgt.md) | 2 | 9 | 15 | 4 | 30 |
|
||
| `base/passport` | [module-base-passport.md](module-base-passport.md) | 8 | 7 | 6 | 4 | 25 |
|
||
| `base/sender` | [module-base-sender.md](module-base-sender.md) | 4 | 12 | 12 | 6 | 34 |
|
||
| `ec/address` | [module-ec-address.md](module-ec-address.md) | 2 | 7 | 6 | 4 | 19 |
|
||
| `ec/mall` | [module-ec-mall.md](module-ec-mall.md) | 5 | 13 | 19 | 8 | 45 |
|
||
| `ec/market` | [module-ec-market.md](module-ec-market.md) | 2 | 8 | 9 | 5 | 24 |
|
||
| `ec/order` | [module-ec-order.md](module-ec-order.md) | 7 | 12 | 10 | 5 | 34 |
|
||
| `finance/wallet` | [module-finance-wallet.md](module-finance-wallet.md) | 5 | 11 | 8 | 6 | 30 |
|
||
| `social/feed` | [module-social-feed.md](module-social-feed.md) | 3 | 13 | 14 | 7 | 37 |
|
||
| `social/group` | [module-social-group.md](module-social-group.md) | 0 | 13 | 12 | 6 | 31 |
|
||
| `social/relation` | [module-social-relation.md](module-social-relation.md) | 1 | 15 | 14 | 4 | 34 |
|
||
| **合计** | 18 个模块 | **52** | **183** | **205** | **102** | **542** |
|
||
|
||
> 计数说明:`base/cloud` 的 P0 为 agent 原始上报,主流程复核后认为其中 P0-1/P0-2/P0-3 应下调(见下「主流程复核记录」);`social/feed` 经 agent 自查将 JWT 密钥一项由 P0 下调为 P1(理由:生产是否注入 `BSM_JwtSecretKey` 无法从仓库确认)。按上述修正,全仓 **P0 = 48**(52 − 3 − 1),其余级别不变。
|
||
> `base/mgt` 计数以报告第 6 节为准(P0=2/P1=9/P2=15/P3=4);报告正文编号 1–31,其中 P2-17 为主流程通知后修正机制的一项。
|
||
|
||
### 各模块最高风险速览
|
||
|
||
| 模块 | 最高风险(摘要,详见各模块报告) |
|
||
| --- | --- |
|
||
| `base/passport` | `Forget.Reset` 无鉴权改他人密码并写裸 MD5;登录/注册接口不校验 `code`;JWT 密钥缺省为公开常量 `Cblocksmesh2022C` → 零成本接管任意账号 |
|
||
| `base/sender` | 短信/邮件接口无鉴权、日限额计数器只有读没有写、验证码可无限爆破 → 短信轰炸/费用损失/账号接管 |
|
||
| `ec/order` | 订单/购物车/优惠券定位与写入信任客户端入参且无归属校验 → 读他人收货信息、任意订单置为已支付、核销任意券;`confirm.go` 必然 panic |
|
||
| `finance/wallet` | 支付回调不入账 + `Payment.Callback` 由客户端决定"支付成功" + 支付宝渠道 `Body` 未初始化必然 panic |
|
||
| `ec/mall` | 仓库内公开的 32 字节占位 JWT 密钥可直接用于签发 HS256 token,叠加"角色/店铺归属全采信 claims、写操作无租户隔离" → 接管任意店铺 |
|
||
| `base/mgt` | root 默认口令 `123456` 自动播种 + JWT 密钥默认值 + 50 个管理接口仅粗粒度 `RequireAdmin` → 接管最高权限 |
|
||
| `base/cloud` | 照片表无 `passport_id`、照片接口靠 `album_id` 反查(**已复核为非越权**);分享口令明文存储与比较、加解密密钥完全由客户端决定 |
|
||
| `social/feed` | 动态写操作无属主校验 + 可见性控制被默认值击穿 → 读写删全站动态 |
|
||
| `social/relation` | 命名返回指针未初始化必然 panic(无 recover)→ 远程打挂进程;好友/关注/标签列名系统性错配 → 静默假成功 |
|
||
| `base/logs` | IP 校验逻辑反向 + `X-Forwarded-For` 可伪造 + 路由全匿名 → 伪造审计日志、读取全量日志 |
|
||
| `base/cms` | 写接口仅校验"任意有效 JWT"无归属校验;`Site` 5 个接口空实现却返回成功 |
|
||
| `ec/address` | `Get/Modify/Delete` 无 `owner_identity` 校验 → 枚举读改删全站收货人 PII;`Fetch` 裸 return 恒返回 nil |
|
||
| `base/feedback` | `Get/Delete/Remark` 无鉴权无归属校验;`Modify` 覆盖 `identity` → 工单失联、子表脱钩 |
|
||
| `base/fts` | 客户端可控 `bucket` 直接拼入落盘路径 → `..` 穿越任意目录写;MinIO 分支可写任意桶 |
|
||
| `base/initial` | `Config` 把可控 `os` 拼进 `ORDER BY` → SQL 注入;6 个字典接口无鉴权无限流 |
|
||
| `base/ads` | 独立入口网关整体 404;唯一接口无鉴权无限流且 `pos_key` 无索引全表扫描 |
|
||
| `social/group` | 13 个 RPC 中 12 个确定性缺陷(表名/列名错、结果被丢弃、权限与 SQL 全错);`Disband` 是返回 OK 的模板 TODO |
|
||
| `ec/market` | 管理接口只验签名不验角色/归属 → 自审通过、删他人代理商、拉全量身份证;代理商登录签发的 token 不是 JWT |
|
||
|
||
## 汇总 TODO(跨模块优先事项)
|
||
|
||
按"先止血、再治本"排序。每条对应各模块报告中的具体 TODO 项,验收标准见对应文件。
|
||
|
||
### 阶段一:P0 止血(上线前必须完成)
|
||
|
||
- [ ] **T1 统一密钥治理**|动作:`Authorization.Key`、SDK `JWT_SECRET_KEY`、各模块 `SecretKey` 全部改为强制注入且启动期校验(拒绝 `CHANGE_ME*`、`Cblocksmesh2022C`、`4ef05311358cd1c8f787281f08b38b1c` 等任何仓库内出现过的值;长度校验之外增加熵/黑白名单校验)|验收:以仓库内任意历史占位符启动必须失败|涉及:`pkgs/all/etc/default_dev.yaml:22`、`pkgs/ecmall/etc/default_dev.yaml:22`、SDK `crypto/token/jwt.go:34`、`module/base/mgt/internal/logic/pub/login.go:90`、`module/ec/mall/internal/config/config.go:41`
|
||
- [ ] **T2 账号接管链路封堵**|动作:`Forget.Reset` 接入真实验证码校验与身份校验;`Login.Code/Quick`、`Register.Code` 真正校验 `code`;删除 MD5 写入路径;为 `passport_account` 补 `account`/`phone` 唯一索引|验收:无 `code` 无法登录、无法改他人密码、库中不再产生 MD5 口令|涉及:`module/base/passport/internal/logic/forget/reset.go:31`、`login/code.go:17`、`login/quick.go:20`、`register/code.go:13`、`internal/logic/common/token.go`
|
||
- [ ] **T3 资金与交易完整性**|动作:支付回调真正入账并加签名验签与幂等;`Payment.Callback` 禁止客户端置状态;`AliPay.Body/ctx` 初始化;订单/优惠券/购物车全部补服务端归属校验;`confirm.go` panic 修复并加 recovery 拦截器|验收:伪造回调不能改状态、并发下单不超卖、越权订单操作返回 403|涉及:`module/finance/wallet/internal/logic/payment/callback.go:25`、`alipay/alipay.go:15,53`、`module/ec/order/internal/logic/**`
|
||
- [ ] **T4 越权与无鉴权接口收敛**|动作:按各模块报告清单补齐 `ParseMetaCtx` + 归属过滤 + 角色校验;独立入口禁止裸奔(补鉴权或直接不暴露)|验收:以 A 账号 token 访问 B 账号资源全部 403/404|涉及:`base/feedback`(`method/get.go:19`)、`base/logs`(`routers/register.go:23` 注释掉的 JwtAuth)、`ec/address`(`library/get.go:29`)、`ec/market`(`agency/approve.go:15`)、`ec/mall`、`base/cms`、`social/feed`、`base/sender`、`base/initial`
|
||
- [ ] **T5 远程 panic / DoS 修复**|动作:修所有 nil 解引用与无保护类型断言,并为全部 gRPC server 装配 recovery 拦截器|验收:`go test -run` 与手工用例下不再 panic,进程不退出|涉及:`social/relation`(`friend/tag_fetch.go:22`、`friend/apply_get.go:32`)、`finance/wallet`(`alipay.go:53`)、`ec/order`(`confirm.go:62`)、`base/logs`(`log/fetch.go:29,45`)、`ec/address`(`library/fetch.go:16-40`)
|
||
- [ ] **T6 上传路径穿越**|动作:对 `bucket`/文件名做白名单与 `filepath.Clean` + 前缀校验(或改用服务端映射表);MinIO 桶名同样校验|验收:`bucket=../../x` 与 `%2e%2e%2f` 均被拒|涉及:`module/base/fts/internal/logic/handler.go:27`、`provider.go:26,99`
|
||
- [ ] **T7 SQL 注入点修复**|动作:`Config` 的 `os` 改为参数化或白名单枚举排序|验收:注入 payload 不再进入 SQL|涉及:`module/base/initial/internal/logic/check/config_cache.go:21`
|
||
|
||
### 阶段二:P1 治本
|
||
|
||
- [ ] **T8 修复 S-1 网关模板缺陷**|动作:`internal/server/new.go` 初始化 `gwRuntime.NewServeMux()` 并注册 handler;`cmd/main` 改用 `service.Expose`;或明确关闭 `Gateway.Enable` 并同步文档|验收:独立二进制下文档中的 REST 路由可达|涉及:全部 18 个模块的 `internal/server/new.go`、`service/expose.go`、`cmd/main/main.go`
|
||
- [ ] **T9 修复 S-3 token 签发不一致**|动作:`ec/market`、`ec/mall` 的登录改用与聚合网关一致的 HS256 JWT 签发|验收:B 端登录 token 可通过 `pkgs/ecmall` 网关校验|涉及:`module/ec/market/internal/logic/agency/login.go:53`、`module/ec/mall/internal/logic/staff/login.go:88`
|
||
- [ ] **T10 数据完整性**|动作:补事务包围多表写入、去掉 `Select()+Updates(结构体)` 的零值覆盖、修正被改写的主键、补唯一索引与幂等|验收:并发与重复提交下无脏数据|涉及:`base/mgt`(`user/modify.go:64`、`permission/modify.go:140`)、`base/feedback`(`method/modify.go:37,89`)、`ec/order`、`base/cloud`(`album/delete_album.go:45-54`)、`ec/address`(默认地址)
|
||
- [ ] **T11 明文凭据与 PII 治理**|动作:轮换仓库/`etc`/`.builds` 中出现的所有口令与密钥;PII 加密存储 + 日志脱敏 + 关闭生产 gorm Debug|验收:仓库与构建产物中扫描不到真实凭据;日志无明文 PII|涉及:`module/base/feedback/etc/feedback_prod.yaml:4`、`.builds/etc/feedback_prod.yaml:4`、`scripts/build-all-linux.sh:100`、`module/base/cloud`(分享口令)、`module/finance/wallet`(银行卡/身份证)、`module/ec/market`(证件资料)
|
||
- [ ] **T12 未实现接口显式化**|动作:所有模板桩与空实现改为返回 `codes.Unimplemented` 或补齐实现,禁止"假成功"|验收:调用未实现接口返回明确错误而非 OK|涉及:`base/cms`(`site/*`)、`social/group`(`Disband`)、`ec/market`(`data/*`)、`base/sender`(`TencentSender`)、`finance/wallet`(转账/放款)
|
||
- [ ] **T13 限流与审计日志**|动作:登录/短信/上传/写接口加限流;管理端高危操作留审计痕迹;短信/邮件日限额计数器落写入侧|验收:超阈值请求被限流并有记录|涉及:`base/sender`、`base/mgt`、`base/logs`
|
||
- [ ] **T14 启动与迁移解耦**|动作:拆分连接/迁移/seed,关闭生产 `AutoMigrate` 与 `Debug`,补真实迁移脚本(仓库当前无 `.sql`)|验收:只读实例与蓝绿发布可用|涉及:全模块 `internal/impl`、`internal/models`
|
||
|
||
### 阶段三:P2/P3 收尾
|
||
|
||
- [ ] **T15 可观测性与优雅退出**|补 `/health`、结构化日志、`context.WithTimeout`、可用的大盘指标;修 `defer srv.Stop()` 因 SDK `select{}` 永不执行的问题|涉及:全模块 `cmd/main`
|
||
- [ ] **T16 测试补齐**|优先覆盖认证、权限、越权、订单状态机、并发扣款/核销、优惠券、崩溃路径;修复当前失败/失效的既有测试(如 `module/base/fts/internal/routers/register_test.go` 路由断言 FAIL、`.http` 服务名大小写错误)|涉及:各模块 `test/`
|
||
- [ ] **T17 清理死代码与失效文档**|移除零引用包(如 `base/fts/internal/{response,errors}`、各模块 `cmd/cli` Hello World、`grpcConns`、`MemorySerice` 等),修正 README/wiki 与实现不符的描述(缓存策略、`/health`、Makefile、Dockerfile 等)|涉及:全仓
|
||
- [ ] **T18 配置一致性**|`prod` 与 `dev` 配置不得字节级相同;修正 `Service:` 名与模块不符(如 `ec/address` 的 etc 写 `Service: order`);统一命名与拼写(`MemorySerice`)|涉及:各模块 `etc/*.yaml`
|
||
- [ ] **T19 补充 scope 说明**|`module/ec/supply`(仅 README)、`module/finance/bill`、`module/finance/loan`(空目录)、`social/relation/service`(空目录、缺 `expose.go`)需明确归属或补齐|验收:目录不再有"空壳"歧义
|
||
|
||
## 主流程复核记录
|
||
|
||
审计 agent 的结论并非全部可信,主流程对高危结论逐一回读源码复核,修正如下(未单独说明的 P0 均已被源码证据直接证实):
|
||
|
||
| 模块 | agent 结论 | 复核结果 |
|
||
| --- | --- | --- |
|
||
| `base/passport` | `Forget.Reset` 无鉴权改他人密码并写裸 MD5;三个验证码登录接口不校验 `code` | **成立**。`internal/logic/forget/reset.go:18-31`(仅校验非空后按 `identity` 直改 `password`,且写入 `utils.Md5`);`internal/logic/login/code.go:17-21`(只判空即签发 token) |
|
||
| `base/initial` | `Config` 接口把调用方可控 `os` 拼进 `ORDER BY` | **成立**。`internal/logic/check/config_cache.go:21` 字符串拼接进 `Order()`,GORM 无法参数化该位置 |
|
||
| `base/mgt` | 初始化种子内置 root/123456 | **成立**。`internal/models/init_db.go:15-16`;`:145` 仅打印"请尽快修改默认密码" |
|
||
| `social/relation` | `TagFetch` 命名返回指针未初始化导致必然 panic | **成立**。`internal/logic/friend/tag_fetch.go:15,22` 对未初始化的 `*pb.FriendTagsReply` 直接 `Count(&reply.Total)`,且 `internal/server/new.go:23` 的 `grpc.NewServer()` 无 recover 拦截器 → 可远程打挂进程。同源问题见 `ec/address/library/fetch.go:16-40`(裸 `return` 恒返回 nil) |
|
||
| `base/feedback` | Get/Delete/Remark 无鉴权无归属校验;Modify 覆盖 identity | **成立**。`internal/logic/method/get.go:19-29` 全文无 `ParseMetaCtx`,查询仅 `Where("identity = ?")`;`internal/logic/method/modify.go:37` 写入新 `utils.UUID()` 作 `Identity`,`:89` 再 `Updates(record)` → 业务主键被改写、子表 `item_identity` 脱钩 |
|
||
| `base/cms` | 写接口仅校验"任意有效 JWT",无归属校验 | **成立**。`internal/logic/post/delete.go:29` 显式传空 author 过滤并留 `// Todo:`;`internal/logic/site/create.go:20-27` 为模板桩却返回 `vars.OK`(假成功) |
|
||
| `social/feed` | 动态写操作无属主校验 | **成立**。`internal/logic/post/remove.go:17-25` 仅 `ParseMetaCtx` 后即 `models.DeletePost(in.Identity)`,无属主过滤;`delete_comment.go:17-24` 同构 |
|
||
| `social/group` | `Disband` 为返回 OK 的模板 TODO;`Modify` 会随机重写群 `identity` | **成立**。`internal/logic/basic/disband.go:26` 为 `// TODO: add your logic code` 且函数返回成功;`internal/logic/basic/modify.go:33` 写入随机 `utils.UUID()` 作 `Identity`,`:35` 再 `UpdateColumns(record)` 全列写入(含 `identity` 与零值 `PassportID`/`MemberTotal`) |
|
||
| `ec/mall` | 公开占位 JWT 密钥可直接签发 HS256 token | **成立**。`pkgs/all/etc/default_dev.yaml:22` 与 `pkgs/ecmall/etc/default_dev.yaml:22` 的 `CHANGE_ME_32_BYTE_JWT_SECRET_KEY` 恰为 **32 字节**,通过 SDK `crypto/token/jwt.go:34-36` 的长度校验,并被 `pkgs/all/internal/server/authorization.go:39,78` 直接用作 HS256 签名密钥 → 可离线伪造管理员 token(两个聚合入口均受影响) |
|
||
| `base/cloud` | P0-1/2/3:照片无 `passport_id` 导致跨用户照片读写删与相册级联删除越权 | **高估,需下调**。`internal/models/cloud_photo.go` 确实没有 `passport_id`,但照片级接口通过 `JOIN cloud_albums ... WHERE cloud_albums.passport_id = ?` 强制归属校验(`album/delete_photo.go:31-32`、`album/get_photo.go:31`、`album/update_photo.go:32`、`album/list_photos.go:36,44`);`album/set_cover_photo.go:32` 校验相册归属、`:39` 校验照片属于该相册;`album/delete_album.go:31` 按 `passport_id` 限定待删相册。**不构成越权**。其中两个子问题独立成立并保留:`delete_album.go:45-54` 两次删除无事务(非原子),以及 `CloudPhoto` 缺 `passport_id` 属反规范化脆弱设计(可降级为 P1/P2) |
|
||
|
||
## 跨模块系统性缺陷(主流程独立确认)
|
||
|
||
以下问题不是单个模块的偶发缺陷,而是模板/生成器级别的共性,建议在汇总层单独立项修复,而不是在 18 个模块里各修一遍。
|
||
|
||
### S-1(P0):所有模块的独立部署入口没有可用的 HTTP 网关
|
||
|
||
证据链(主流程已逐个核对):
|
||
|
||
1. `internal/server/new.go` 声明了 `Mux *gwRuntime.ServeMux` 字段(如 `module/base/sender/internal/server/new.go:16`),但 `New()` 只注册 gRPC server(`:33-34`),**从不调用 `gwRuntime.NewServeMux()`,`Mux` 恒为 nil**;全仓库 `gwRuntime.NewServeMux()` 仅出现在 `pkgs/all/internal/server/server.go:38` 与 `pkgs/ecmall/internal/server/server.go:38`。
|
||
2. 每个 `service/expose.go` 把 `options.Gateway` 直接传给生成的 `pb.Register*HandlerServer`(如 `module/base/sender/service/expose.go:30,33`)。
|
||
3. 生成的注册函数对 nil mux 无任何防御,第一行即 `mux.Handle(...)`(如 `module/base/sender/pb/sms.pb.gw.go:97-98`)→ 传入 nil 立即 panic。
|
||
4. 独立部署的 `cmd/main/main.go` 只调用 `server.New(nil)` 并自行 `net.Listen`,**从不调用 `service.Expose`**,因此独立二进制下网关要么整体 404、要么在接入 `Expose` 时启动即 panic。
|
||
|
||
影响:`ads`、`initial`、`address`、`cms`、`cloud`、`ftS` 等多个模块的审计都独立报告了「独立部署 HTTP 网关 404 / Mux 为 nil」,根因是同一处模板缺陷。README 宣称的独立部署 REST 入口在该形态下不可用。
|
||
|
||
### S-2(P1):`infra.Response` 为包级单例且被并发写
|
||
|
||
`bsm-sdk/core/infra/response.go` 的 `Response` 是包级变量、方法直接改字段,`fts` 与 `logs` 两个模块均独立报告了并发响应串包/数据竞争风险。属 SDK 级缺陷,需在 SDK 侧改为每次请求新建响应对象或加锁。
|
||
|
||
### S-3(P0):两套不兼容的 token 签发方式,B 端登录 token 被聚合网关拒绝
|
||
|
||
聚合入口的鉴权中间件**只接受 HS256 JWT**:`pkgs/all/internal/server/authorization.go:73-79` 与 `pkgs/ecmall/internal/server/authorization.go:73-79` 使用 `jwt.ParseWithClaims` 并强制 `WithValidMethods(["HS256"])`。
|
||
|
||
而各模块签发 token 的路径分成两类:
|
||
|
||
| 模块 | 位置 | 实际产物 | 与聚合网关兼容 |
|
||
| --- | --- | --- | --- |
|
||
| passport(登录/注册全部 4 处) | `internal/logic/common/token.go:10` → `token.New(...).GenerateJwt(...)` | 真正 JWT(函数名有误导性) | ✅ |
|
||
| mgt | `internal/logic/pub/login.go:90`、`refresh.go:28` → `GenerateJwt` | 真正 JWT | ✅ |
|
||
| **ec/market** | `internal/logic/agency/login.go:53` → `encipher.GenerateTokenAes` | **AES-CBC + base64,不是 JWT** | ❌ |
|
||
| **ec/mall** | `internal/logic/staff/login.go:88` → `encipher.GenerateTokenAes` | **AES-CBC + base64,不是 JWT** | ❌ |
|
||
|
||
证据:`bsm-sdk/core/crypto/encipher/encipher.go` 的 `GenerateTokenAes` 最终调用 `AesEncryptCBC` + `base64.StdEncoding`,输出形状为密文 base64,无法被 `jwt.ParseWithClaims` 解析。
|
||
|
||
影响:market 代理商与 mall 员工登录成功后拿到的 token **无法通过聚合入口网关校验**,B 端登录链路在该拓扑下不可用(P0 可用性问题,非安全漏洞)。`market` 的审计已独立发现该点(P0-2),`mall` 的审计需一并核对。
|
||
|
||
## 汇总 TODO
|
||
|
||
(待回填)
|