本文介紹如何使用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外掛程式
- 管理員修改參數,啟用SQL/Protect外掛程式功能。
set polar_sql_protect.enabled = on; #(預設off) set polar_sql_protect.level = passive; #(learn/active/passive三種模式,預設passive) - 管理員建立測試資料庫targetdb、測試使用者test。
CREATE DATABASE targetdb; CREATE ROLE test; GRANT ALL ON DATABASE targetdb TO test; ALTER ROLE test LOGIN; - 管理員登入資料庫targetdb,建立外掛程式並添加受保護角色。
CREATE EXTENSION sqlprotect; SELECT sqlprotect.protect_role('test');查看受保護角色列表。SELECT * FROM sqlprotect.list_protected_users; SELECT * FROM sqlprotect.polar_sql_protect; - 管理員可以根據需要修改外掛程式運行模式,具體操作如下:
外掛程式有learn、active、passive三種工作模式,預設為passive,詳情參見設定角色的保護模式。
- 管理員修改外掛程式運行模式為learn。
polar_sql_protect.level = learn; #(learn/active/passive三種模式,預設passive)- 使用test使用者登入資料庫targetdb,建立測試表company並執行查詢、插入語句:
CREATE TABLE company(name VARCHAR(100), employee_num INT); SELECT * FROM company; INSERT INTO company VALUES('new', 1); SELECT * FROM company; - 管理員查看外掛程式學習到的test使用者使用的表資訊。
SELECT * FROM sqlprotect.polar_sql_protect_rel; SELECT * FROM sqlprotect.list_protected_rels;
- 使用test使用者登入資料庫targetdb,建立測試表company並執行查詢、插入語句:
- 管理員修改外掛程式模式為passive。
polar_sql_protect.level = passive; #(learn/active/passive三種模式,預設passive)- 使用test使用者登入資料庫targetdb。
- 執行SQL注入語句。
SELECT * FROM company WHERE 1 = 1; DELETE FROM company;說明 外掛程式提示非法SQL語句,但是不阻斷SQL語句的執行。
- 管理員修改外掛程式模式為active。
polar_sql_protect.level = active; #(learn/active/passive三種模式,預設passive)- 使用test使用者登入資料庫targetdb。
- 執行SQL注入語句。
SELECT * FROM company WHERE 1 = 1; DELETE FROM company;說明 外掛程式提示非法SQL語句,並且阻斷SQL語句的執行。
- 管理員修改外掛程式運行模式為learn。
設定受保護的角色
受保護的角色被儲存在表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');