SQL 注入是数据库安全最顽固的威胁之一。即便开发团队严格执行预编译与输入过滤,遗留代码、第三方组件或人为疏忽依然可能留下突破口。金仓数据库(KingbaseES)V009R002C014 内置的 SQL 防火墙提供了一种数据库内生的主动防护方案——不依赖应用层代码修复,直接从内核层识别并阻断恶意 SQL,让安全团队从「疲于补漏」转向「规则先行」。
一、SQL 注入原理
SQL 注入就像不速之客通过门缝溜进房子:攻击者将恶意代码伪装成正常输入,诱导数据库执行意外操作。
典型攻击示例
场景 1:绕过登录认证
用户在登录表单输入 ' OR '1'='1 作为用户名,原本安全的查询被篡改为恒真条件,绕过所有认证:
-- 正常查询
SELECT * FROM users WHERE username = 'alice' AND password = 'secret';
-- 注入后:OR '1'='1' 恒为真,直接绕过认证,返回所有用户数据
SELECT * FROM users WHERE username = '' OR '1'='1' AND password = 'anything';
场景 2:删表破坏
攻击者在 ID 参数中注入 1; DROP TABLE users;--,利用分号执行第二条 DDL 语句:
-- 正常查询
SELECT * FROM users WHERE id = '42';
-- 注入后:分号分隔出第二条语句,整张表被删除
SELECT * FROM users WHERE id = '1'; DROP TABLE users; --';
场景 3:联合查询拖库
通过 UNION 拼接查询敏感系统表,批量获取账号信息:
-- 注入 UNION,将系统用户信息拼入结果集
SELECT id, name FROM products WHERE id = '0'
UNION SELECT usename, passwd FROM pg_shadow; --';
传统防御的局限
预编译(参数化查询)是最常见的应对手段,能有效绑定变量、阻止注入:
-- 安全写法:$1/$2 为绑定变量,注入字符串无法改变语句结构
PREPARE login_stmt AS
SELECT * FROM users WHERE username = $1 AND password = $2;
EXECUTE login_stmt('alice', 'secret');
但预编译依赖开发者在每一处数据库调用中正确实施。一旦存在遗留的动态 SQL 拼接、第三方 ORM 漏洞或开发者疏漏,防线就会出现缺口。相比之下,SQL 防火墙在数据库端全局检查,无论应用层是否做了防护,均能兜底拦截。
二、SQL 防火墙原理概述
SQL 防火墙的核心功能是防止数据库执行非法 SQL,且不影响合法 SQL 的正常执行。防火墙会学习合法 SQL 并组成白名单,启用防护后只允许白名单内的 SQL 正常执行。当攻击者利用 SQL 注入等漏洞试图执行恶意语句时,防火墙识别并拦截不在白名单内的 SQL,预防注入或恶意操作。
防火墙读取 KingbaseES 对 SQL 的解析结果计算特征值。DML 语句中的常量(如 WHERE id = 1 与 WHERE id = 99)不影响特征值,因此不会因业务数据变化产生误报。
金仓 SQL 防火墙分为三种模式,可灵活配置:
| 模式 | 行为 | 适用场景 |
|---|---|---|
| 学习模式 | 自动将执行的 SQL 记录为白名单规则 | 初次部署,采集合法业务 SQL |
| 警告模式 | SQL 正常执行,非白名单 SQL 写入告警日志 | 测试白名单完整性,观察覆盖情况 |
| 报错模式 | 非白名单 SQL 被阻断,返回错误并写日志 | 正式上线,全面拦截非法请求 |
三、核心优势
1. 99.99% 准确率
SQL 防火墙对所有数据库连接的所有 SQL 进行全量检查,无法被绕过。只有白名单内的合法 SQL 可以正常执行;执行不在白名单内的非法 SQL 会发出警告或被拦截报错。同时,防火墙读取 KingbaseES 对 SQL 的解析结果计算特征值,DML 类 SQL 中的常量不影响特征值计算,对读写操作的具体数值不敏感,大幅降低误报率。
为验证拦截能力,我们对 100 万条合法 SQL 和 900 万条非法 SQL 进行多轮实测:
| 指标 | 数量 |
|---|---|
| 合法 SQL 总数 | 100 万 |
| 非法 SQL 总数 | 900 万 |
| 被检出的非法 SQL | 900 万(检出率 100%) |
| 被误拦的合法 SQL | 0 |
| 未被检出的非法 SQL | 0 |
综合准确率:99.99%
2. 性能稳定,损耗极低
作为 KingbaseES 原生集成的内部插件,无需开发者进行额外的复杂操作,也不会导致性能大幅损耗,更不会存在生态适配问题。我们在 100 个会话并发执行 500 条不同 SQL 的场景下,测试数据库每秒的吞吐量,经过多轮测试,发现损耗在 6% 以下,性能损耗主要来自 SQL 重复查询。
警告模式性能表现:
| 非法 SQL 占比 | 0% | 1% | 3% | 5% | 10% |
|---|---|---|---|---|---|
| 性能损耗 | -5.61% | -5.55% | -5.99% | -5.66% | -5.67% |
报错模式性能表现:
非法 SQL 会在执行之前被拦截并报错,但仍算入吞吐量,所以非法 SQL 占比越高,测得的吞吐量越大属于正常现象。
| 非法 SQL 占比 | 0% | 1% | 3% | 5% | 10% |
|---|---|---|---|---|---|
| 性能损耗 | -5.70% | -2.83% | -1.48% | +0.07% | +4.94% |
3. 两步完成配置,自动建立白名单
管理员只需指定学习哪些用户的 SQL,然后由 SQL 防火墙在学习模式下自动获取 SQL 规则即可,无需手动制定详细规则,避免因人为失误导致白名单规则难以全面覆盖,增加误报或漏报的风险。同时支持按用户级防护,更加灵活。
四、配置操作演示
以下以 KingbaseES V009R002C014 为例,展示 SQL 防火墙的完整配置流程。
第一步:启用插件
-- 在 kingbase.conf 中添加预加载库(需重启数据库生效)
-- shared_preload_libraries = 'sql_firewall'
-- 重启后,在目标数据库中创建扩展
CREATE EXTENSION sql_firewall;
第二步:进入学习模式,采集白名单
-- 使用安全管理员身份操作
-- 为目标用户开启学习模式
SELECT sql_firewall.set_firewall_mode('app_user', 'learning');
-- 查看当前各用户防火墙状态
SELECT * FROM sql_firewall.status();
学习期间让业务系统正常运行,防火墙自动采集合法 SQL 作为白名单。
第三步:切换警告模式,验证白名单
-- 切换为警告模式,观察是否有合法业务 SQL 被误报
SELECT sql_firewall.set_firewall_mode('app_user', 'warning');
-- 查看告警日志,确认非白名单 SQL 的来源
SELECT username, query, fired_at
FROM sql_firewall.firewall_log
ORDER BY fired_at DESC
LIMIT 20;
-- 如有误报,将对应 SQL 手动加入白名单
SELECT sql_firewall.add_rule('app_user', 'SELECT id, name FROM orders WHERE user_id = $1');
若告警日志中无误报,说明白名单已覆盖全部合法业务 SQL,可进入下一步。
第四步:切换报错模式,正式防护
-- 正式上线,开启拦截
SELECT sql_firewall.set_firewall_mode('app_user', 'enforcing');
-- 验证:模拟注入攻击,以下语句不在白名单,将被阻断
SELECT * FROM users WHERE username = '' OR '1'='1';
-- ERROR: sql_firewall: query is not in the whitelist
五、总结
SQL 防火墙将复杂的 SQL 防护功能简化为「学习、警告、报错」三种模式,能够自动学习规则,并根据规则校验、拦截 SQL 语句。这将被动的、滞后的防护与补救,转变为主动学习、可管理的规则与全面的校验拦截,实现风险前置预防。
善用 KingbaseES 的 SQL 防火墙,能够让数据库拥有辨别「友军」与「异己」的能力,让所有数据都得到妥善保护:
- 全量检查:所有连接、所有 SQL,无死角覆盖,不能被绕过
- 自动学习:无需手写规则,避免人为失误导致漏报
- 内核集成:原生插件,性能损耗 <6%,无额外部署成本
- 灵活策略:按用户粒度配置,支持学习 / 警告 / 报错三种模式
金仓数据库 KingbaseES 已广泛应用于党政、交通、能源等高安全要求行业领域。金仓数据库将进一步实现「预警先行,牢筑防线」,为企业提供安全可靠的数据使用环境。Kingbase 的 SQL 防火墙为数据库安全构筑起一道安全之门,严格把守每一条访问数据库的 SQL,保护数据的安全。