本文介绍如何使用SQL/Protect插件保护数据库防止SQL注入攻击。
背景信息
防止SQL注入攻击通常是数据库应用开发者的责任,数据库管理者的防御能力较小。SQL/Protect插件通过传入的查询请求来判断SQL注入的发生。一旦发现潜在的危险查询,便向数据库管理员报警,并及时阻断查询的执行。
可以防御的SQL注入攻击类型
攻击类型 | 说明 |
---|---|
Unauthorized Relations攻击 | 表的访问限制功能对于数据库管理员来说是一项繁琐的事情。SQL/Protect插件提供了一个学习模块,动态跟踪一位用户访问的表之间的关联关系。该模块可以在学习模式(leanrn)下主动学习一个用户访问的表集合,当插件进入被动模式(passive)或者主动模式(active)后,便可以根据学习得到的表集合来检查传入查询的合法性。 |
Utility Commands攻击 | 在SQL注入攻击中经常会用到一些常用命令,像典型的DDL(Data Definition Language)语句。例如:创建用户定义的函数来访问其他表的数据。SQL/Protect插件能够阻断这些在应用程序中通常不使用的SQL命令的运行。 |
SQL Tautology攻击 | 这是最常见的SQL注入攻击方式,通过在WHERE条件中添加true表达式来绕过条件限制,例如:WHERE password = 'x' OR 'x'='x' 。攻击者通常使用该技术来试探数据库的缺陷,SQL/Protect插件可以阻断任何使用true表达式的查询语句。
|
Unbounded DML Statements攻击 | Unbounded DML Statements是一类不受条件限制的数据库更新语句,例如:没有WHERE条件的UPDATE/DELETE操作。攻击者通常使用该操作来更新/删除用户的密码库造成DoS攻击。 |
受保护的角色
受保护角色是指被该插件保护的用户或者组,受保护角色可以由数据库管理员通过SQL/Protect插件指定。该插件支持为不同的角色制定不同级别的SQL注入保护,不同的级别包含不同的攻击类型。
超级用户不可以成为受保护角色。但是受保护的角色可能升级为超级用户,此时,SQL/Protect插件执行以下操作:
- 受保护的超级用户执行的每条命令都会产生警报信息。
- 如果SQL/Protect插件运行在主动模式(active),则阻断受保护的超级用户执行的每个命令。
因此,当SQL/Protect插件运行时,一个受保护的拥有超级用户权限的角色,或者被修改为普通用户,或者将其还原为不受保护的角色。
另外,受保护角色执行的每一个命令都会被记录到一个统计视图中,该视图可以用于识别一个潜在攻击的开始。统计数据收集后,按照不同的攻击类型进行划分。
说明 数据库默认受保护角色的最大数量
max_protected_roles
为64、受保护表的最大数量max_protected_relations
为1024。
在特定的数据库使用SQL/Protect插件
设置受保护的角色
受保护的角色被存储在表polar_sql_protect中,数据库管理员可以选择需要保护的用户/组,将其添加到该表中。
- 执行protect_role函数,添加用户到受保护角色列表中。
SELECT sqlprotect.protect_role('userA');
- 查询插件学习到的受保护角色的表内容。
select * from sqlprotect.list_protected_users; select * from sqlprotect.polar_sql_protect;
- 执行unprotect_role函数,可解除某个受保护的角色。
SELECT sqlprotect.unprotect_role('userA');
设置角色的保护模式
参数polar_sql_protect.level决定了受保护角色的保护模式,一共有三种保护模式:learn、passive和active,默认为passive。
保护模式 | 说明 |
---|---|
learn | 可以追踪用户的行为,并记录用户使用的表,用于建立受保护角色期望的行为。 |
passive | 当受保护角色执行非法SQL语句时,进行报警,但不阻断SQL语句的执行,可被用于行为监控。 |
active | 阻断受保护角色的所有非法SQL语句的执行,表现为SQL防火墙在攻击者进行渗透测试时便可以起作用,该模式不仅阻断攻击路径,而且还跟踪查询SQL语句,以便于管理员早于攻击者发现数据库的不足之处。 |
例如,设置保护模式为active。
polar_sql_protect.level = active; #设置保护模式为active
修改表polar_sql_protect的某些字段,可以设置一个角色受保护的内容。
targetdb=# \d sqlprotect.polar_sql_protect;
Table "sqlprotect.polar_sql_protect"
Column | Type | Collation | Nullable | Default
--------------------+---------+-----------+----------+---------
dbid | oid | | not null |
roleid | oid | | not null |
protect_relations | boolean | | |
allow_utility_cmds | boolean | | |
allow_tautology | boolean | | |
allow_empty_dml | boolean | | |
Indexes:
"polar_sql_protect_pkey" PRIMARY KEY, btree (roleid)
例如,设置受保护角色16480的allow_utility_cmds为TRUE,即拦截受保护角色16480执行的Utility Commands攻击SQL。
UPDATE sqlprotect.polar_sql_protect SET allow_utility_cmds = TRUE WHERE roleid = 16480;
其他功能介绍
- 关闭SQL/Protect插件功能:
polar_sql_protect.enabled = off #(默认off) polar_sql_protect.level = passive #(learn/active/passive三种模式,默认passive)
- 查看被拦截的SQL语句的统计信息:
SELECT * FROM sqlprotect.polar_sql_protect_stats;
- 删除某位用户的被拦截的SQL语句统计信息:
SELECT sqlprotect.drop_stats('username');