签入脚本

This commit is contained in:
小蚂蚁云
2026-10-20 11:37:25 +08:00
commit 7f5e8470af
909 changed files with 4045080 additions and 0 deletions
+124
View File
@@ -0,0 +1,124 @@
================================================================================
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;时钟偏移极小场景不受影响)。