EnterpriseDB的SQL注入攻击保护功能一

enterprisedb是基于postgresql的企业级数据库(即PPAS)。

 

PPAS(Postgres Plus Advanced Server) 提供了SQL注入攻击保护,按下面讲
 a 概述
 b 配置
 c 通常维护操作
 d 备份/恢复sql注入保护数据库
 

SQL注入攻击是黑客对数据库进行攻击的常用手段之一。随着B/S模式应用开发的发展,使用这种模式编写应用程序的程序员也越来越多。但是由于程序员的水平及经验也参差不齐,相当大一部分程序员在编写代码的时候,没有对用户输入数据的合法性进行判断,使应用程序存在安全隐患。用户可以提交一段数据库查询代码,根据程序返回的结果,获得某些他想得知的数据,这就是所谓的SQL Injection,即SQL注入。SQL注入是从正常的WWW端口访问,而且表面看起来跟一般的Web页面访问没什么区别,所以目前市面的防火墙都不会对SQL注入发出警报,如果管理员没查看IIS日志的习惯,可能被入侵很长时间都不会发觉。但是,SQL注入的手法相当灵活,在注入的时候会碰到很多意外的情况,需要构造巧妙的SQL语句,从而成功获取想要的数据。

PPAS提供SQL注入攻击保护。SQL注入攻击保护一般是应用开发人员的责任,数据库管理员则无能为力。PPAS通过检查传入的SQL提供SQL注入攻击保护。
SQL保护提供给数据库管理员反馈潜在的危险查询和阻塞这些查询。

1
概述
这届介绍各种不同种类的SQL注入攻击和SQL注入攻击保护是怎么防止攻击的。

1.1
SQL注入攻击类型
有多种不同技术的SQL注入攻击,每种技术都有某种signature。SQL注入攻击检查查询中是否有下列signature:
a Unauthorized Relations/未授权的关系
PPAS允许管理员对关系的访问进行控制,但很多管理员不做这些乏味的工作。
SQL注入攻击保护(SQL/Protect)提供了一个学习模型对用户访问的关系进修跟踪。
这也许管理员确认应用程序的负载,并且,SQL/Protect也学习哪些用户会访问哪些关系。
当SQL/Protect被切到被动或主动模式时,会对传入的查询检查要学习的关系。

b Utility Commands/工具命令
在SQL注入攻击中经常会用到一些常用命令,像典型的DDL语句。例如创建用户定义函数以访问系统其他资源。
SQL/Protect能够阻塞这些在应用程序中通常不使用的SQL命令的运行。

c SQL Tautology/ 同意的SQL
在SQL注入攻击中使用最频繁的技术是在WHERE子句中增加部分内容,例如WHERE password = 'x' OR 'x'='x',
攻击者通常以这种方式寻找安全薄弱环节,SQL/Protect能够阻塞这类查询。

具体的攻击方法可以参见我转载的《SQL注入攻击》
1.1.1
受保护的角色
监控SQL注入攻击涉及到分析受保护的角色的session里的SQL语句。
受保护的角色是PPAS数据库管理员选择的要监控的数据库角色。(PPAS里,用户和组统称为角色)
每个受保护的角色可定制要监控的SQL注入攻击类型(1.1节中讨论的),从而提供不同程度的保护,并显着地降低了DBA维护用户的工作量。

注意:
    超级用户不能作为受保护的角色。如果受保护的角色后来成了超级用户,该角色的某些行为
    将被显示:
    a 当这个受保护的superuser的每一个sql命令被SQL/Protect抛一个警告信息。
    b 受保护的superuser执行每一个命令,都会在统计信息视图edb_sql_protect_stats中
      的superusers列都会加1.
    c 当SQL/Protect是active模式时,所有受保护superuser用户执行的命令被禁止运行。

1.1.2
攻击统计:
受保护用户的每一个命令被SQL/Protect当作攻击而记录。这些条件能通过试图访问以
识别攻击的开始。
如果受保护用户连接了多个数据库,这个用户的攻击统计信息分别存放在连接的数据库里。
注意:    
数据库运行时SQL/Protect统计信息维护在内存里。数据库停止运行后,这些信息存放在
data/global里面的二进制文件edb_sqlprotect.stat里。

2
配置SQL/Protect
在PPAS的lib目录里必须安装了其程序库文件(linux上是sqlprotect.so,windows上是sqlprotect.dll)SQL/Protect才能运行。
还必须在share/contrib文件夹里有sqlprotect.sql脚本。

必须配置数据库服务器使用SQL/Protect,并且配置每一个要监控的数据库。
    a 必须配置postgresql.conf相关参数
    b 必须在要监控的数据库里安装SQL/Protect要用的数据库对象。
    
配置步骤1:
修改postgresql.conf里的如下参数:
    shared_preload_libraries: 增加$libdir/sqlprotect
    custom_variable_classes: 增加edb_sql_protect
    edb_sql_protect.enabled: 是否激活SQL/Protect,默认是off,最后设这个。
    edb_sql_protect.level: 设置当SQL命令执行时SQL/Protect采取的行为。
                           缺省是passive。初始时设置为learn。
  edb_sql_protect.max_protected_roles: 设置保护的最大用户数。默认是64个
  edb_sql_protect.max_protected_relations: 设置每个用户保护的最大关系数。默认是1024个。

例如:
shared_preload_libraries = '$libdir/dbms_pipe,$libdir/edb_gen,$libdir/plugins/plugin_debugger,$libdir/plugins/plugin_spl_debugger,$libdir/sqlprotect'
# (change requires restart)
custom_variable_classes = 'dbms_pipe, dbms_alert, edb_sql_protect' # list of custom variable class names
edb_sql_protect.enabled = off
edb_sql_protect.level = learn
edb_sql_protect.max_protected_roles = 64
edb_sql_protect.max_protected_relations = 1024

配置步骤2:
重启数据库

配置步骤3:
以superuser连接到每个受保护的数据库并运行share/contrib里的sqlprotect.sql脚本。
这个脚本创建了模式sqlprotect并在里面创建数据库对象。
下面的例子显示了在数据库edb里
$ /opt/PostgresPlus/9.1AS/bin/psql -d edb -U enterprisedb
Password for user enterprisedb:
psql (9.1.1.0)
Type "help" for help.
edb=# \i /opt/PostgresPlus/9.1AS/share/contrib/sqlprotect.sql
CREATE SCHEMA
GRANT
SET
CREATE TABLE
GRANT
。。。

2.1
选择受保护的角色
现在受保护的角色和保护级别。

2.1.1
设置受保护角色列表
对于每一个受保护的数据库,确定要监控的角色/用户增加到该数据库的受保护角色列表。
步骤一:
连接到数据库
$ /opt/PostgresPlus/9.1AS/bin/psql -d edb -U enterprisedb
Password for user enterprisedb:
psql (9.1.1.0)
Type "help" for help.
edb=#

步骤二:
把模式sqlprotect设置到查询路径
edb=# SET search_path TO sqlprotect;
SET

--增加-- create user appuser password 'appuser';

步骤三:
受保护的角色维护在表edb_sql_protect里,用函数protect_role('rolename')增加角色。
增加角色appuser
--ERROR:  SQLPROTECT: Protected user hash not initialized
edb=# SELECT protect_role('appuser');
protect_role
--------------
(1 row)

从表中验证结果:
edb=# SELECT * FROM edb_sql_protect;
dbid | roleid | protect_relations | allow_utility_cmds | allow_tautology | allow_empty_dml
-------+--------+-------------------+--------------------+-----------------+-----------------
13917 | 16671 | t | f | f | f
(1 row)

从视图中验证结果:
edb=# \x
Expanded display is on.
edb=# SELECT * FROM list_protected_users;
-[ RECORD 1 ]------+--------
dbname | edb
username | appuser
protect_relations | t
allow_utility_cmds | f
allow_tautology | f
allow_empty_dml | f

2.1.2
设置保护级别
edb_sql_protect.level设置保护级别,其决定受保护用户执行sql语句时SQL/Protect的行为。
其定义的级别决定的行为应用到该数据库服务器上所有数据库中受保护的用户上。

edb_sql_protect.level看设置的值为:
learn: 跟踪受保护用户的行为和记录其用到的表。初始时设置。
passive: 如果受保护的角色违反了定义的规则,抛一个警告,但不中断然后sql的执行。
         这是SQL/Protect学习了保护角色的期望行为后要设置这个。
active:为受保护角色停止执行所有无效语句。就像sql防火墙一样不让危险语句执行。
默认为passive,如果第一次用SQL/Protect,设置edb_sql_protect.level为learn

2.2
监控受保护的角色
一旦配置了SQL/Protect、受保护用户、保护级别,就可以运行应用程序了。
接着应该确定受保护的角色应该可以访问哪些关系。learn模式允许SQL/Protect记录
受保护用户访问过的关系到该角色的受保护关系列表 edb_sql_protect_rel里。

当SQL/Protect运行于passive或active模式时保护免受攻击的监控就开始了。
在passive或active模式时,角色允许访问受保护关系列表里的关系。

但是,如果角色尝试访问其受保护关系列表里的关系之外的关系,SQL/Protect会返回
一个warnning或error。该sql语句是否被执行依赖于模式是passive还是active。

2.2.1
learn模式

步骤1:
在postgresql.conf里配置如下参数:
edb_sql_protect.enabled = on
edb_sql_protect.level = learn

步骤2:
加载postgresql.conf文件
以超级用户连接到数据库,执行下面的函数pg_reload_conf().
edb=# SELECT pg_reload_conf();
pg_reload_conf
----------------
t
(1 row)

步骤3:
允许受保护用户运行其应用
以受保护角色appuser在psql里运行下面的sql。
edb=> SELECT * FROM dept;
NOTICE: SQLPROTECT: Learned relation: 16384
deptno | dname | loc
--------+------------+----------
10 | ACCOUNTING | NEW YORK
20 | RESEARCH | DALLAS
30 | SALES | CHICAGO
40 | OPERATIONS | BOSTON
(4 rows)
edb=> SELECT empno, ename, job FROM emp WHERE deptno = 10;
NOTICE: SQLPROTECT: Learned relation: 16391
empno | ename | job
-------+--------+-----------
7782 | CLARK | MANAGER
7839 | KING | PRESIDENT
7934 | MILLER | CLERK
(3 rows)
上面的NOTICE指明关系增加到了该用户的受保护关系列表里。

在learn模式里,不阻止怀疑sql的运行,但或给一个notice提醒
edb=> CREATE TABLE appuser_tab (f1 INTEGER);
NOTICE: SQLPROTECT: This command type is illegal for this user
CREATE TABLE
edb=> DELETE FROM appuser_tab;
NOTICE: SQLPROTECT: Learned relation: 16672
NOTICE: SQLPROTECT: Illegal Query: empty DML
DELETE 0

步骤4:
以受保护用户运行的应用,会查询受保护的表以观察/发现增加到该角色的受保护关系列表里的关系。
以超级用户连接到监控的数据库并设置查询路径包含模式sqlprotect
edb=# SET search_path TO sqlprotect;
SET

在表edb_sql_protect_rel里查看增加到受保护关系列表里的关系:
edb=# SELECT * FROM edb_sql_protect_rel;
dbid | roleid | relid
-------+--------+-------
13917 | 16671 | 16384
13917 | 16671 | 16391
13917 | 16671 | 16672
(3 rows)
在试图list_protected_rels里查看更易于理解的信息
edb=# SELECT * FROM list_protected_rels;
Database | Protected User | Schema | Name | Type | Owner
----------+----------------+--------+-------------+-------+--------------
edb | appuser | public | dept | Table | enterprisedb
edb | appuser | public | emp | Table | enterprisedb
edb | appuser | public | appuser_tab | Table | appuser
(3 rows)

2.2.2
passive模式

用到确定受保护角色的应用已经访问了其要用到的所有关系,就可以改变保护级别
以加快传入的SQL语句而防止sql注入攻击。

passive模式是两个保护模式passive和active里不严格的。

步骤1
在postgresql.conf里配置如下参数,激活SQL/Protect为passive模式
edb_sql_protect.enabled = on
edb_sql_protect.level = passive

步骤2
加载postgresql.conf文件
以超级用户连接到数据库,执行下面的函数pg_reload_conf().
edb=# SELECT pg_reload_conf();
pg_reload_conf
----------------
t
(1 row)

以appuser运行下面的语句,没有问题,因为已经学习了dept和emp。
edb=> SELECT * FROM dept;
deptno | dname | loc
--------+------------+----------
10 | ACCOUNTING | NEW YORK
20 | RESEARCH | DALLAS
30 | SALES | CHICAGO
40 | OPERATIONS | BOSTON
(4 rows)
edb=> SELECT empno, ename, job FROM emp WHERE deptno = 10;
empno | ename | job
-------+--------+-----------
7782 | CLARK | MANAGER
7839 | KING | PRESIDENT
7934 | MILLER | CLERK
(3 rows)

运行sql访问不在受保护列表里的关系或有危险的sql语句,不会阻止sql运行,但会给一个warning。
edb=> CREATE TABLE appuser_tab_2 (f1 INTEGER);
WARNING: SQLPROTECT: This command type is illegal for this user
CREATE TABLE
edb=> INSERT INTO appuser_tab_2 VALUES (1);
WARNING: SQLPROTECT: Illegal Query: relations
INSERT 0 1
edb=> INSERT INTO appuser_tab_2 VALUES (2);
WARNING: SQLPROTECT: Illegal Query: relations
INSERT 0 1
edb=> SELECT * FROM appuser_tab_2 WHERE 'x' = 'x';
WARNING: SQLPROTECT: Illegal Query: relations
WARNING: SQLPROTECT: Illegal Query: tautology
f1
----
1
2
(2 rows)

步骤3
监控可疑行为的统计信息

通过查询视图edb_sql_protect_stats,可以查看访问不在受保护列表里的关系
和有危险的sql的次数。
视图edb_sql_protect_stats列如下:
username:受保护角色的名字
superusers:当受保护角色是超级用户时执行的sql语句数。
relations:访问量受保护关系列表里没有的关系的sql语句的数量
commands: 受保护角色运行的DDL语句的数
tautology: 受保护角色运行的包含同意条件的sql语句数
dml: 受保护角色运行的不包含where子句的update和delete语句数

查一个看看
edb=# SET search_path TO sqlprotect;
SET
edb=# SELECT * FROM edb_sql_protect_stats;
username | superusers | relations | commands | tautology | dml
----------+------------+-----------+----------+-----------+-----
appuser | 0 | 3 | 1 | 1 | 0
(1 row)

2.2.3
active模式
active模式里,不允许sql语句执行,而且,或抛一个error代替warning。

步骤1

在postgresql.conf里配置如下参数,激活SQL/Protect为passive模式
edb_sql_protect.enabled = on
edb_sql_protect.level = active

步骤2
加载postgresql.conf文件
以超级用户连接到数据库,执行下面的函数pg_reload_conf().
edb=# SELECT pg_reload_conf();
pg_reload_conf
----------------
t
(1 row)

以appuser执行sql语句:
edb=> CREATE TABLE appuser_tab_3 (f1 INTEGER);
ERROR: SQLPROTECT: This command type is illegal for this user
edb=> INSERT INTO appuser_tab_2 VALUES (1);
ERROR: SQLPROTECT: Illegal Query: relations
edb=> SELECT * FROM appuser_tab_2 WHERE 'x' = 'x';
ERROR: SQLPROTECT: Illegal Query: relations

查询统计信息
edb=# SELECT * FROM sqlprotect.edb_sql_protect_stats;
username | superusers | relations | commands | tautology | dml
----------+------------+-----------+----------+-----------+-----
appuser | 0 | 5 | 2 | 1 | 0
(1 row)
 


你可能感兴趣的:(数据库,PostgreSQL,PostgreSQL,sql注入攻击,sql注入攻击包含)