暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

PolarDB PostgreSQL版(兼容Oracle)的SQL防火墙

成子 2023-12-25
342

本文介绍如何使用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插件

  1. 管理员修改参数,启用SQL/Protect插件功能。


     

    set polar_sql_protect.enabled = on; #(默认off)
    set polar_sql_protect.level = passive; #(learn/active/passive三种模式,默认passive)
  2. 管理员创建测试数据库targetdb、测试用户test。


     

    CREATE DATABASE targetdb;
    CREATE ROLE test;
    GRANT ALL ON DATABASE targetdb TO test;
    ALTER ROLE test LOGIN;
  3. 管理员登录数据库targetdb,创建插件并添加受保护角色。


     

    CREATE EXTENSION sqlprotect;
    SELECT sqlprotect.protect_role('test');

    查看受保护角色列表。


     

    SELECT * FROM sqlprotect.list_protected_users;
    SELECT * FROM sqlprotect.polar_sql_protect;
  4. 管理员可以根据需要修改插件运行模式,具体操作如下:

    插件有learn、active、passive三种工作模式,默认为passive,详情参见设置角色的保护模式

    • 管理员修改插件运行模式为learn。


       

      polar_sql_protect.level = learn; #(learn/active/passive三种模式,默认passive)
      1. 使用test用户登录数据库targetdb,建立测试表company并执行查询、插入语句:


         

        CREATE TABLE company(name VARCHAR(100), employee_num INT);
        SELECT * FROM company;
        INSERT INTO company VALUES('new', 1);
        SELECT * FROM company;
      2. 管理员查看插件学习到的test用户使用的表信息。


         

        SELECT * FROM sqlprotect.polar_sql_protect_rel;
        SELECT * FROM sqlprotect.list_protected_rels;
    • 管理员修改插件模式为passive。


       

      polar_sql_protect.level = passive; #(learn/active/passive三种模式,默认passive)
      1. 使用test用户登录数据库targetdb。
      2. 执行SQL注入语句。


         

        SELECT * FROM company WHERE 1 = 1;
        DELETE FROM company;

        说明

        插件提示非法SQL语句,但是不阻断SQL语句的执行。

    • 管理员修改插件模式为active。


       

      polar_sql_protect.level = active; #(learn/active/passive三种模式,默认passive)
      1. 使用test用户登录数据库targetdb。
      2. 执行SQL注入语句。


         

        SELECT * FROM company WHERE 1 = 1;
        DELETE FROM company;

        说明

        插件提示非法SQL语句,并且阻断SQL语句的执行。

设置受保护的角色

受保护的角色被存储在表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');
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论