Files
EasyGoAdmin_GoFrame_EleVue/document/wiki/17_安全设计专题.txt
T
2026-10-20 11:37:25 +08:00

125 lines
9.0 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
================================================================================
EasyGoAdmin 后端开发者文档 · 17 安全设计专题
================================================================================
按威胁面组织,每项给出控制措施与代码落点,便于安全评审与自查。
--------------------------------------------------------------------------------
1. 威胁 → 控制总表
--------------------------------------------------------------------------------
威胁面 控制措施 代码落点
------------------ -------------------------------------- ------------------
身份伪造 HS256 签名校验+iss/exp 强校验 utility/jwt Parse
令牌重放(登出后) jti 黑名单,TTL=剩余有效期 blacklist:token:{jti}
Refresh 重放 轮换:旧 refresh 入黑名单,已黑即拒 logic/auth Refresh
被踢会话复活 强退同时拉黑 access+refresh 双令牌 online_user ForceLogout*
口令窃取/泄露 bcrypt(password+salt);日志脱敏 utility/crypto;
access_token/refresh_token/password 不落日志 middleware maskSecret
暴力破解 登录/验证码/令牌兑换独立严阈值 10/min/IP rateLimit.authLimit
水平越权(跨租户) dao.Ctx 注入 tenant_id IN(0,自身) hooks.ApplyCtx
行级越权(部门/本人) 角色 data_scope 四档叠加过滤 logic/data_scope.go
(仅列表/导出;写操作由 permission 兜底) ApplyDataScope
垂直越权 gmeta permission + HasPerm;超管放行 Bind 包装层
注入(SQL) 全链 gdb 参数化;无方言拼接红线 dao/Where 参数化
参数篡改 gvalid 标签校验(Parse 统一触发) api/v1 结构体标签
存储型 XSS .svg 强制 attachment+nosniff middleware/response
富文本外链不本地化、占位符契约 base.go Localize
SSRF 富文本仅处理本站 URL,外站一律不抓取 localizeOne 判定
CSRF Bearer 头令牌(非 Cookie)+ CORS 白名单 JWT 中间件/CORS
IP 伪造 仅受信代理(api.proxyIps,支持 CIDR) realClientIP
的 XFF/X-Real-IP 生效
限流绕过 计数经 Redis 跨实例共享;窗口起点对齐 RateLimit incrCounter
越权写(演示站) Demo 中间件拦截全部写操作 middleware/demo
审计缺失 操作日志异步全量记录(脱敏+响应+耗时) OperationLog
会话固定 无服务端 Cookie 会话,令牌全部服务端签发 auth Login
敏感信息出栈 GetUser 永不返回 password/salt;详情页
令牌原文仅在线用户详情(需权限) index/online_user
--------------------------------------------------------------------------------
2. 认证安全细节
--------------------------------------------------------------------------------
* 令牌:HS256,密钥与签发者可配置(jwt.secret/issuer);Parse 限定
WithValidMethods(HS256) 防算法混淆;exp 必填。
* 双令牌分工:access 2h 只作身份;refresh 7d 且仅 /api/oauth2/token 可用
(typ 校验,access 不能当 refresh 用)。
* 验证码:一次性(命中即删)、TTL 300s、bypassCode 生产必须留空。
* 密码:bcrypt DefaultCost;外部 salt 防彩虹;旧 md5 数据被 IsBcrypt 拒绝
(强制重置升级)。
* 万能码/调试口:仅 captcha.bypassCode 一处,发布检查清单强制清空。
--------------------------------------------------------------------------------
3. 授权安全细节
--------------------------------------------------------------------------------
* 权限点粒度:到接口级(sys:module:action),按钮级由前端按 permissions 控制;
后端不做按钮级校验——新增接口必须同时声明 permission 或显式留空(留空
= 登录即可,评审需明确该选择)。
* 数据权限(行级):租户隔离(硬规则,不可配置)+ 角色 data_scope(可配置,
两层独立叠加)。data_scope 四档:1-全部 2-本部门及以下 3-本部门 4-仅本人;
多角色取最宽松;超管/平台绕过;未分配部门用户挂部门档降级为仅本人;
仅作用于挂接 ApplyDataScope 的模块之 Page/List/导出(applyFilters 链),
Detail/Update/Delete 不过滤,由 permission 节点与租户隔离兜底。
* 权限缓存一致性:保存权限/分配角色/角色改数据范围主动清 identity 缓存,
最迟 300s 过期。
* 隐藏节点:menu hide=1 的权限节点不进 Perms(LoadIdentity 过滤 hide=0),
不能用 hide 表达“禁用权限”——用 status。
--------------------------------------------------------------------------------
4. 租户隔离红线(安全审计重点)
--------------------------------------------------------------------------------
1) 业务代码禁止 g.DB() 直查业务表(绕过钩子与过滤);
2) 业务代码禁止手写 del_flag / tenant_id 条件(应由 dao.Ctx 注入);
3) 新增租户级表必须登记 hooks.tenantTables(漏登=跨租户泄漏);
4) 唯一预检范围必须等于唯一索引范围(否则 1062 漏报/误报);
5) 平台级(超管)全量可见是设计预期,管理端点须收紧 permission。
--------------------------------------------------------------------------------
5. 文件上传安全链
--------------------------------------------------------------------------------
大小限制 → 扩展名白名单 → 图片魔数嗅探 → 随机文件名(防猜路径/覆盖)
→ 临时/正式两段式(未过校验不进正式目录)→ 静态响应 svg 附件化+nosniff
→ 定期清理 temp。注意:fileExt 白名单含 js/css/sql 等——如对公网用户提供
上传,建议按环境收紧 fileExt(配置层控制,无需改码)。
--------------------------------------------------------------------------------
6. 日志与审计合规
--------------------------------------------------------------------------------
* 操作日志:登录后全部带 log 标签接口的操作均可追溯(操作人/参数/响应/IP/
归属地/UA/耗时/结果);密码与令牌字段脱敏。
* 登录日志:成功/失败/退出全记录,失败含原因。
* 日志保留:job.logRetentionDays(默认 90 天)物理清理——合规要求更长
保留期时调大配置。
* 审计字段:create_user/update_user 由 hooks 强制盖章(取登录名),
业务不可伪造(经 ctx 注入;无 ctx 的后台任务写 daemon/空)。
--------------------------------------------------------------------------------
7. 部署安全基线(生产)
--------------------------------------------------------------------------------
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)
--------------------------------------------------------------------------------
8. 已知边界与取舍(诚实声明)
--------------------------------------------------------------------------------
* CheckUnique 为先查后插的 UX 预检,存在 TOCTOU——并发唯一性以 uk_* 索引
为最终防线(捕获 1062 翻译提示)。
* 数据权限(data_scope)仅约束 Page/List/导出;Detail/Update/Delete
不做行级过滤——越权改删他人记录的防线是接口 permission 节点 + 租户隔离。
管理端点授予权限时应评估该角色是否应拥有写权限。
* 数据权限当前仅 user 模块接线(dept_id 列);其他模块行级可见性由
租户隔离单层兜底。
* 部门子树查询(deptSubtreeIds)每次全量拉部门表 BFS,无缓存——部门表
数百行内无感知,成千上万行时需加短时缓存。
* 身份缓存(300s)窗口内,直接改库的 dept_id/data_scope 不经 API 不会
即时生效(API 路径均主动清缓存,见 15 章)。
* 在线用户详情返回令牌原文(便于运维排查),依赖 sys:onlineUser:detail
权限收口。
* 操作日志 param 截断 8KB、响应截断 8KB,超长报文不完整留存。
* 无独立的密码复杂度策略/定期更换策略(业务层未强制,可按需在 index/
user 密码路径追加规则)。
* 无物理防重放窗口(jti 黑名单依赖 TTL;时钟偏移极小场景不受影响)。