安全专题
安全基线
Juice 本身不替代应用安全控制。建议把安全分为三层:
SQL 构造层(参数绑定、动态片段)
应用层(输入校验、鉴权、审计)
数据库层(账号权限、连接策略)
参数绑定规则(必须)
在 mapper 中优先使用 #{}:
#{name}:预编译参数,占位符绑定,推荐。${name}:字符串直拼,存在注入风险,仅在受控场景使用。
安全示例:
<select id="GetUsers">
SELECT id, name
FROM users
WHERE name = #{name}
</select>
高风险示例(避免):
<select id="DangerousSearch">
SELECT * FROM users WHERE ${rawWhere}
</select>
动态 SQL 安全模式
1) 动态排序白名单
var orderByWhitelist = map[string]string{
"created_at": "created_at",
"name": "name",
"id": "id",
}
func SafeOrderBy(input string) string {
if v, ok := orderByWhitelist[input]; ok {
return v
}
return "created_at"
}
然后再将安全值传给 mapper(即使使用 ${},值也来自白名单)。
2) 动态表名白名单
分表场景下,不直接信任请求参数;先映射成已知表名。
3) IN 列表限长
无论是 foreach 还是手写 SQL,限制列表长度,防止超长 SQL 与资源耗尽。
日志与审计
生产环境避免输出敏感参数(手机号、身份证、token、密码等)。
建议在调试中间件前增加脱敏中间件。
对关键写操作记录审计字段(操作者、请求 ID、时间、来源)。
数据库权限最小化
读写分离账号:读账号仅
SELECT,写账号仅必要DML。禁止业务账号使用
DROP/ALTER等高危权限。按服务拆分数据库账号,避免共享高权限凭据。
事务与安全
不要把跨数据源写入当成一个本地事务(见“多数据源 × 事务交互”)。
对资金、库存等关键路径,结合幂等键和唯一约束,防止重放与并发穿透。
发布前安全检查清单
mapper中是否存在未经白名单约束的${}。Debug 日志是否会泄露敏感参数。
数据库账号权限是否最小化。
高风险接口是否有鉴权、限流与审计。
动态查询是否有上限(分页、IN 长度、超时)。