本文介紹如何使用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');