SQL防火牆
標籤
PostgreSQL , SQL防火牆 , 注入 , HOOK
背景
SQL隱碼攻擊通常是業務層做的事情,例如使用繫結變數,使用關鍵字過濾等手段,避免被SQL隱碼攻擊。
另一方面,資料庫也有類似的功能,例如SQL防火牆。
PostgreSQL內建了很多的HOOK,這些HOOK可以方便開發者加入一些功能,例如在SQL parser階段的HOOK,可以加入一些SQL統計,SQL篡改,SQL REWRITE的功能。
在SQL執行階段的HOOK,可以用來拒絕執行等。
共享記憶體分配階段的HOOK,可以用來分配使用者自定義程式的共享記憶體等。
SQL_FIREWALL是PostgreSQL的一個SQL防火牆外掛,利用了一些HOOK,實現了SQL防火牆的功能。
/* Saved hook values in case of unload */
static shmem_startup_hook_type prev_shmem_startup_hook = NULL;
static post_parse_analyze_hook_type prev_post_parse_analyze_hook = NULL;
static ExecutorStart_hook_type prev_ExecutorStart = NULL;
static ExecutorRun_hook_type prev_ExecutorRun = NULL;
static ExecutorFinish_hook_type prev_ExecutorFinish = NULL;
static ExecutorEnd_hook_type prev_ExecutorEnd = NULL;
static ProcessUtility_hook_type prev_ProcessUtility = NULL;
1、shmem_startup_hook_type 內部程式通訊
src/backend/storage/ipc/ipci.c
/*
* CreateSharedMemoryAndSemaphores
* Creates and initializes shared memory and semaphores.
*
* This is called by the postmaster or by a standalone backend.
* It is also called by a backend forked from the postmaster in the
* EXEC_BACKEND case. In the latter case, the shared memory segment
* already exists and has been physically attached to, but we have to
* initialize pointers in local memory that reference the shared structures,
* because we didn`t inherit the correct pointer values from the postmaster
* as we do in the fork() scenario. The easiest way to do that is to run
* through the same code as before. (Note that the called routines mostly
* check IsUnderPostmaster, rather than EXEC_BACKEND, to detect this case.
* This is a bit code-wasteful and could be cleaned up.)
*
* If "makePrivate" is true then we only need private memory, not shared
* memory. This is true for a standalone backend, false for a postmaster.
*/
void
CreateSharedMemoryAndSemaphores(bool makePrivate, int port)
{
...
/*
* Now give loadable modules a chance to set up their shmem allocations
*/
if (shmem_startup_hook)
shmem_startup_hook();
}
2、parser hook
src/backend/parser/analyze.c
/* Hook for plugins to get control at end of parse analysis */
post_parse_analyze_hook_type post_parse_analyze_hook = NULL;
/*
* parse_analyze
* Analyze a raw parse tree and transform it to Query form.
*
* Optionally, information about $n parameter types can be supplied.
* References to $n indexes not defined by paramTypes[] are disallowed.
*
* The result is a Query node. Optimizable statements require considerable
* transformation, while utility-type statements are simply hung off
* a dummy CMD_UTILITY Query node.
*/
Query *
parse_analyze(RawStmt *parseTree, const char *sourceText,
Oid *paramTypes, int numParams,
QueryEnvironment *queryEnv)
{
ParseState *pstate = make_parsestate(NULL);
Query *query;
Assert(sourceText != NULL); /* required as of 8.4 */
pstate->p_sourcetext = sourceText;
if (numParams > 0)
parse_fixed_parameters(pstate, paramTypes, numParams);
pstate->p_queryEnv = queryEnv;
query = transformTopLevelStmt(pstate, parseTree);
if (post_parse_analyze_hook)
(*post_parse_analyze_hook) (pstate, query);
free_parsestate(pstate);
return query;
}
其他的HOOK不再贅述,簡單來說,SQL 防火牆的功能是:
學習資料庫中被呼叫的SQL,記錄被呼叫的SQL到規則庫,根據規則庫的內容,防止呼叫不在規則庫的SQL(根據配置)。
sql firewall的功能介紹
1、學習模式,將SQL PARSER後的值儲存起來。儲存在規則表中。(因此支援繫結變數)
2、從外部CSV檔案匯入到規則中。
3、當不在規則中的SQL被執行時,根據配置 返回錯誤(不允許執行),或返回警告(允許執行)。
4、記錄警告、錯誤的次數。
sql firewall的用法
1、配置postgresql.conf
* shared_preload_libraries
sql_firewall module needs to be loaded in the
shared_preload_libraries parameter as following:
shared_preload_libraries = `sql_firewall`
Note for developers
-------------------
pg_stat_statements built with `--enable-cassert` causes assert when
queryId already has non-zero value.
So, to use both pg_stat_statements and sql_firewall at the same
time, pg_stat_statements needs to be loaded prior to sql_firewall
in the shared_preload_libraries parameter as following.
shared_preload_libraries = `pg_stat_statements,sql_firewall`
Then, sql_firewall can skip queryId calculation if queryId is
already set by pg_stat_statements, and avoid the assert.
* sql_firewall.firewall
sql_firewall.firewall is able to take one of the following values:
`disabled`, `learning`, `permissive` and `enforcing`.
The default value is `disabled`.
* sql_firewall.max
最多能存多少條規則。
Number of queries the SQL Firewall can learn.
It can take an int value between 100 and INT_MAX.
The default value is 5000.
The queries which exceed this value in the "learning" mode would never
be learned.
2、如果使用者一開始並不知道資料庫中會執行哪些SQL,通常可以設定為學習模式,學習一個月,基本上能跑的SQL都能學到。
* sql_firewall.firewall = learning
3、當然,如果使用者知道這個資料庫會執行哪些SQL,那麼可以將SQL匯入。
必須為disabled模式,才能匯入。
* sql_firewall_import_rule(`/path/to/rule.txt`)
sql_firewall_import_rule() reads the firewall rules from the
specified CSV file.
This function is available only under the disabled mode with
superuser privilege.
4、規則固定下來後,sql_firewall.firewall設定為enforcing模式,不允許執行不在規則中的SQL。
5、或者sql_firewall.firewall設定為permissive模式,允許執行,但是發出告警。
sql firewall函式介面
* sql_firewall_reset()
sql_firewall_reset() clears the firewall rules.
This function is available only under the disabled mode with
superuser privilege.
* sql_firewall_stat_reset()
sql_firewall_reset() clears the counters of warning and error. Only
available with superuser privilege.
* sql_firewall_export_rule(`/path/to/rule.txt`)
sql_firewall_export_rule() writes the firewall rules in the
specified CSV file.
This function is available only under the disabled mode with
superuser privilege.
* sql_firewall_import_rule(`/path/to/rule.txt`)
sql_firewall_import_rule() reads the firewall rules from the
specified CSV file.
This function is available only under the disabled mode with
superuser privilege.
sql firewall管理檢視
* sql_firewall.sql_firewall_statements
sql_firewall_statements view shows the firewall rules and execution
counter for each query.
postgres=# select * from sql_firewall.sql_firewall_statements;
userid | queryid | query | calls
--------+------------+---------------------------------+-------
10 | 3294787656 | select * from k1 where uid = ?; | 4
(1 row)
postgres=#
* sql_firewall.sql_firewall_stat
sql_firewall_stat view has two counters: "sql_warning" and
"sql_error".
"sql_warning" shows number of executed queries with warnings in the
"permissive" mode.
"sql_error" shows number of prevented queries in the "enforcing"
mode.
postgres=# select * from sql_firewall.sql_firewall_stat;
sql_warning | sql_error
-------------+-----------
2 | 1
(1 row)
postgres=#
例子
* Permissive mode
postgres=# select * from sql_firewall.sql_firewall_statements;
WARNING: Prohibited SQL statement
userid | queryid | query | calls
--------+------------+---------------------------------+-------
10 | 3294787656 | select * from k1 where uid = 1; | 1
(1 row)
postgres=# select * from k1 where uid = 1;
uid | uname
-----+-------------
1 | Park Gyu-ri
(1 row)
postgres=# select * from k1 where uid = 3;
uid | uname
-----+-----------
3 | Goo Ha-ra
(1 row)
postgres=# select * from k1 where uid = 3 or 1 = 1;
WARNING: Prohibited SQL statement
uid | uname
-----+----------------
1 | Park Gyu-ri
2 | Nicole Jung
3 | Goo Ha-ra
4 | Han Seung-yeon
5 | Kang Ji-young
(5 rows)
postgres=#
* Enforcing mode
postgres=# select * from k1 where uid = 3;
uid | uname
-----+-----------
3 | Goo Ha-ra
(1 row)
postgres=# select * from k1 where uid = 3 or 1 = 1;
ERROR: Prohibited SQL statement
postgres=#
參考
https://github.com/uptimejp/sql_firewall
相關文章
- 23C新特性SQL防火牆 (SQL Firewall)SQL防火牆
- WAb防火牆與傳統防火牆防火牆
- 防火牆防火牆
- 防火牆(firewall)防火牆
- 防火牆IPTABLES防火牆
- RouterOS防火牆ROS防火牆
- iptables防火牆防火牆
- 防火牆配置防火牆
- 防火牆入侵於檢測——————3、思科 PIX 防火牆和 ASA 防火牆產品線防火牆
- AutoRun病毒防火牆如何使用 AutoRun病毒防火牆教程防火牆
- 軟體防火牆與硬體防火牆詳解防火牆
- 全面分析防火牆及防火牆的滲透(轉)防火牆
- CentOS 防火牆操作CentOS防火牆
- 防火牆介紹防火牆
- CentOS 7.0防火牆CentOS防火牆
- linux 防火牆Linux防火牆
- 防火牆透明模式防火牆模式
- 配置防火牆示例防火牆
- 電影:防火牆防火牆
- 防火牆部署案例防火牆
- ubuntu 關閉防火牆命令 ubuntu怎樣關閉防火牆Ubuntu防火牆
- 選用單防火牆DMZ還是雙防火牆DMZ(轉)防火牆
- 防火牆 搜尋 釋出 防火牆是什麼?怎麼理解?防火牆
- 八種防火牆產品評測(企業級防火牆)(轉)防火牆
- 資料庫防火牆資料庫防火牆
- Iptables防火牆應用防火牆
- iptables防火牆規則防火牆
- LINUX 防火牆 firewalldLinux防火牆
- CentOS 7 防火牆操作CentOS防火牆
- 防火牆的分類防火牆
- CentOS關閉防火牆CentOS防火牆
- entos 7中防火牆防火牆
- ADDS與防火牆防火牆
- CiscoPIX防火牆配置指南防火牆
- linux防火牆iptablesLinux防火牆
- OpenSUSE關閉防火牆防火牆
- linux 防火牆配置Linux防火牆
- Linux 配置防火牆Linux防火牆