跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

如何通过数据库中间件防御SQL注入_在MyCat或ShardingSphere层过滤

数据库中间件不提供可靠的SQL注入防护,真正防护需在驱动层或业务逻辑层实现;MyCat的sqlFilter仅简单匹配关键词,ShardingSphere的SQL解析器默认不拦截,唯一可行策略是强制参数化语句并拒绝裸字符串。 数据库中间件(如 MyCat、ShardingSphere)本身不提供开箱即用的 SQL 注入防护能力,直接依赖它们做“过滤”是危险的误判。真正的防护必须下沉到驱动层或业务逻辑层,中间件只能辅助审计、限流或拦截明显恶意模式——但这类规则极易被绕过。 MyCat 的
sqlFilter
配置根本不可信 MyCat 1.6+ 提供了
server.xml
中的
sqlFilter
开关和白名单机制,但它只匹配 SQL 字符串开头是否为允许类型(如
SELECT
、
INSERT
),不解析语法树,也不校验参数绑定状态。 攻击者用
SELECT/*comment*/+1 FROM users
就能绕过关键词检测
sqlFilter="true"
不会阻止
SELECT * FROM users WHERE name = 'admin' OR '1'='1'
这类已拼接完成的恶意语句 它对
UNION SELECT
的检测基于正则,而
UNI/**/ON SEL/**/ECT
可轻松逃逸 开启后仍需手动维护
whiteList
,但表名、列名等动态部分无法穷举,一加就卡死业务 ShardingSphere 的
SQLParserEngine
不等于防注入 ShardingSphere-Proxy 5.3+ 内置
SQLParserEngine
,能解析 SQL 类型、提取表名、识别参数占位符,但它默认不启用拦截,且解析结果不参与执行决策。 防SQL注入的php类库 防SQL注入的php类库 下载 你不能靠它自动拒绝含
@variable
或字符串拼接的语句——那是业务代码该干的事 它的
sql-comment-parse-cache
和
sql-show
是调试用的,不是安全开关 若强行在
SQLFederationRouter
阶段 throw 异常,会导致分片路由失败,而非阻断注入 真正起作用的是你在
org.apache.shardingsphere.driver.jdbc.core.statement.ShardingSpherePreparedStatement
上做的增强,但这已脱离中间件范畴,进入驱动封装层 中间件唯一靠谱的防御动作:只放行参数化语句 + 拒绝裸字符串 如果你坚持在中间件层设防,唯一可落地的策略是:让中间件拒绝所有未使用占位符的 SQL 请求,并强制要求客户端使用
?
或
$1
占位符。但这需要配套改造客户端行为。 MyCat 需配合自定义
SQLInterceptor
,检查
SQLStatement
是否含
LiteralExpression
(即字面量字符串),有则
throw new RuntimeException("Raw string interpolation forbidden")
ShardingSphere 需在
SQLParseResult
中遍历
ParameterMarkerExpressionSegment
,确认每个值都来自参数而非字符串拼接;否则返回
400 Bad Request
并记录
sql
原文 注意:MySQL 协议层无法区分
SELECT * FROM t WHERE id = ?
和
SELECT * FROM t WHERE id = 123
,所以必须在中间件解析 SQL 后、转发前完成判断 该策略会破坏所有使用
String.format
构建 SQL 的旧代码,上线前必须全量扫描
.executeUpdate(
、
.executeQuery(
等调用点 最易被忽略的一点:MyCat 和 ShardingSphere 都不处理存储过程内部的动态 SQL。如果业务用了
CALL proc_search(?)
,而
proc_search
内部是
EXEC('SELECT * FROM '+@table)
,中间件完全看不见——防护必须延伸到数据库侧的存储过程审查和权限收紧。

相关文章