MySQL SQL 风险拦截:AST 规则、观察模式和可回退阻断

MySQL SQL 风险拦截:AST 规则、观察模式和可回退阻断

MySQL SQL 风险拦截:AST 规则、观察模式和可回退阻断

SQL 风险控制是缩小影响面,不是用 AST 规则消灭慢 SQL。确定性高的无条件更新可以阻断,其余风险先观察、限流并结合执行计划与统计信息判断。

先在网关做可解释的预检

对无条件UPDATEDELETE、明显缺失关联条件的 Join 等高确定性模式,可以在提交前要求显式确认或拒绝。对于大扫描、隐式转换和深层子查询,先标记、限流或进入审核队列;最终仍应结合EXPLAIN、表统计信息和调用方身份判断。

信号合适的处置不宜据此断言的事
无 WHERE 的写操作默认拒绝或人工确认业务一定有问题
隐式类型转换提示参数类型并验证索引一定会全表扫描
Join 条件缺失阻断或要求白名单查询结果一定错误
预估扫描行数偏大限流、异步执行或审核运行时一定超时

风险分数只作为排序依据

如果引入轻量模型,应当输出命中规则、输入特征和模型版本。不要只返回一个不透明分数。阈值需要按业务域配置,并保留白名单与快速回退开关。

def assess(sql: str, estimated_rows: int) -> list[str]: findings = [] normalized = sql.strip().lower() if normalized.startswith(("update ", "delete ")) and " where " not in normalized: findings.append("写操作缺少 WHERE 条件") if estimated_rows > 1_000_000: findings.append("预估扫描行数较高,建议复核执行计划") return findings

让止损动作可恢复

线上先以观察模式运行:记录命中情况、实际耗时和人工结论,再决定哪些规则可以阻断。阻断响应应说明规则编号和申诉方式,审计记录只保存必要的 SQL 指纹与脱敏参数。发生误杀时,能按调用方或规则快速回退,比一套复杂的解析器更重要。