Skip to content

4.10 安全架构设计 ​

概述

安全设计按威胁面组织:每项威胁对应明确控制措施与代码落点。本节给出威胁→控制总表、四条安全红线、部署基线与已知边界(诚实声明),可直接用于安全评审自查。

威胁 → 控制总表 ​

威胁面控制措施代码落点
身份伪造HS256 签名校验 + iss/exp 强校验(限定 HS256 防算法混淆)utility/jwt Parse
令牌重放(登出后)jti 黑名单,TTL=剩余有效期blacklist:{jti}
Refresh 重放轮换:旧 refresh 入黑名单,已黑即拒(1008)logic/auth Refresh
被踢会话复活强退同时拉黑 access+refresh 双令牌online_user ForceLogout
口令窃取/泄露bcrypt(password+salt);日志脱敏(password/salt/token → ***)utility/crypto; maskSecret
暴力破解登录/验证码/令牌兑换独立严阈值 10/min/IPrateLimit.authLimit
水平越权(跨租户)dao.Ctx 注入 tenant_id IN(0,自身)hooks.ApplyCtx
行级越权(部门/本人)角色 data_scope 四档叠加过滤(仅列表/导出;写操作由 permission 兜底)logic/data_scope.go
垂直越权gmeta permission + HasPerm;超管放行Bind 包装层
SQL 注入全链 gdb 参数化;无方言拼接红线dao/Where 参数化
参数篡改gvalid 标签校验(Parse 统一触发)api/v1 结构体标签
存储型 XSS.svg 强制 attachment+nosniff;富文本外链不本地化、占位符契约middleware/response; base.go
SSRF富文本仅处理本站 URL,外站一律不抓取localizeOne 判定
CSRFBearer 头令牌(非 Cookie)+ CORS 白名单JWT 中间件/CORS
IP 伪造仅受信代理(api.proxyIps,支持 CIDR)的 XFF/X-Real-IP 生效realClientIP
限流绕过计数经 Redis 跨实例共享;窗口起点对齐RateLimit incrCounter
越权写(演示站)Demo 中间件拦截全部写操作middleware/demo
审计缺失操作日志异步全量记录(脱敏+响应+耗时)OperationLog
会话固定无服务端 Cookie 会话,令牌全部服务端签发auth Login
敏感信息出栈GetUser 永不返回 password/salt;令牌原文仅在线用户详情(需权限)index/online_user

四条租户隔离红线(安全审计重点) ​

红线清单

  1. 业务代码禁止 g.DB() 直查业务表(绕过钩子与过滤)
  2. 业务代码禁止手写 del_flag / tenant_id 条件(应由 dao.Ctx 注入)
  3. 新增租户级表必须登记 hooks.tenantTables(漏登=跨租户泄漏)
  4. 唯一预检范围必须等于唯一索引范围(否则 1062 漏报/误报)

另:平台级(超管)全量可见是设计预期,管理端点须收紧 permission。

文件上传安全链 ​

text
大小限制 → 扩展名白名单 → 图片魔数嗅探(前 512 字节须 image/*)
→ 随机文件名(防猜路径/覆盖)
→ 临时/正式两段式(未过校验不进正式目录)
→ 静态响应 svg 附件化 + nosniff
→ 定期清理 temp(每日 03:30,tempExpireDays 默认 7 天)

注意:fileExt 白名单含 js/css/sql 等——对公网用户提供上传时,建议按环境收紧 fileExt(配置层控制,无需改码)。

认证与授权安全细节 ​

text
认证:
* 令牌 HS256;密钥/签发者可配置;exp 必填
* 双令牌分工:access 2h 只作身份;refresh 7d 仅 /api/oauth2/token 可用(typ 校验)
* 验证码:一次性(命中即删)、TTL 300s、bypassCode 生产必须留空
* 密码:bcrypt DefaultCost;外部 salt 防彩虹;旧 md5 数据被 IsBcrypt 拒绝(强制重置)

授权:
* 权限点粒度到接口级(sys:module:action),按钮级由前端控制;
  新增接口必须声明 permission 或显式留空(留空=登录即可,评审需明确该选择)
* 隐藏节点:menu hide=1 的权限节点不进 Perms——"禁用权限"用 status 而非 hide
* 权限缓存一致性:保存权限/分配角色/改数据范围主动清 identity 缓存,最迟 300s 过期

部署安全基线(生产) ​

text
1) 修改 jwt.secret 为高强度随机值且与环境隔离
2) captcha.bypassCode=""; app.demo=false; app.errorMsg=false; errorStack=false
3) database/redis 使用独立账号与内网地址;不暴露公网
4) api.proxyIps 只列真实反代出口;未用反代时保持默认(含 127.0.0.1)
5) file.fileExt 按业务收紧;uploadDir 权限最小化;domainUrl 走 CDN/域名隔离
6) rateLimit 按压测调参(防误伤;authLimit 不建议调大)
7) HTTPS 由前置代理终止;服务本身 HTTP 内网
8) 定期核对 /api.json 与权限点清单(防新接口漏配 permission)

已知边界与取舍(诚实声明) ​

项边界
CheckUnique先查后插的 UX 预检,存在 TOCTOU——并发唯一性以 uk_* 索引为最终防线
数据权限仅约束 Page/List/导出;Detail/Update/Delete 防线是 permission 节点 + 租户隔离
接线范围数据权限当前仅 user 模块接线(dept_id 列);其他模块行级可见性由租户隔离单层兜底
部门子树deptSubtreeIds 每次全量拉部门表 BFS 无缓存——数百行内无感知,上万行需加短时缓存
身份缓存窗口300s 内直接改库的 dept_id/data_scope 不经 API 不会即时生效(API 路径均主动清缓存)
在线用户详情返回令牌原文(便于运维排查),依赖 sys:onlineUser:detail 权限收口
日志截断param/result 截断 8KB,超长报文不完整留存
密码策略无独立复杂度/定期更换强制(可按需在密码路径追加规则)
防重放jti 黑名单依赖 TTL 自然过期,无物理防重放窗口

小蚂蚁云团队 · 提供技术支持