Oracle Database 23ai 中的In Database SQL Firewall是数据库安全性的重要保障,其作用不仅仅是嵌入数据库内核并提供实时保护,防范 SQL 注入攻击等外部威胁,而且还在于其细粒度的访问控制机制。通过实时监测和拦截恶意 SQL 语句,In Database SQL Firewall有效地保护了数据库的完整性和机密性,避免了可能导致数据泄露、破坏数据库结构或其他恶意行为的安全漏洞。其对未经授权的 SQL 操作的阻止,进一步确保了数据库内部操作的合法性和安全性,为企业提供了强大的数据安全保障,为业务运行提供了可靠的基础支持。我们可以利用In Database SQL Firewall,建立授权的 SQL 语句,并将其添加到In Database SQL Firewall监视器的“允许列表”中。这样一来,任何符合“允许列表”的 SQL 请求都将被顺利执行,而潜在违反规定的 SQL 请求将会被阻止。此外,In Database SQL Firewall还可以利用会话上下文数据,如 IP 地址、操作系统用户和程序类型等信息,来加强执行控制,确保只有经授权的用户和程序才能执行相应的 SQL 操作,进一步提升了数据库的安全性和可信度。
今天我们就使用Oracle Database 23ai Free版本进行实验,和大家一起体验Oracle Database 23ai中提供的In Database SQL Firewall能力。在今天的实验中,我们的目标是创建一个用户dev1,并且只允许该用户只能对特定表实现select操作,而无法执行其他操作。
首先我们在数据库中创建一个In Database SQL Firewall的管理用户,名字为df_admin,并对该用户授予与In Database SQL Firewall相关的管理权限。之后,创建普通用户,名字为dev1,并授予可以登录数据库的权限。
[oracle@23ai ~]$ sqlplus as sysdba
SQL*Plus: Release 23.0.0.0.0 - Production on Fri Jun 7 05:55:45 2024
Version 23.4.0.24.05
Copyright (c) 1982, 2024, Oracle. All rights reserved.
Connected to:
Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free
Version 23.4.0.24.05
SQL> alter session set container=freepdb1;
Session altered.
SQL> create user DF_ADMIN identified by Oracle_4U;
User created.
SQL> grant create session, sql_firewall_admin, audit_admin to df_admin;
Grant succeeded.
SQL> create user dev1 identified by Oracle_4U;
User created.
SQL> grant create session, create table, unlimited tablespace to dev1;
Grant succeeded.
SQL>
接下来,我们使用刚刚创建的dev1用户登录,并创建本次测试所需的数据表及数据。在这里需要注意的是,如果连接失败,请检查tnsnames.ora文件,您是否已经成功创建了freepdb1这个别名。
[oracle@23ai ~]$ sqlplus dev1/Oracle_4U@freepdb1
SQL*Plus: Release 23.0.0.0.0 - Production on Sat Jun 8 01:36:23 2024
Version 23.4.0.24.05
Copyright (c) 1982, 2024, Oracle. All rights reserved.
Connected to:
Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free
Version 23.4.0.24.05
SQL> create table mytab ( cid VARCHAR2(128), owner VARCHAR2(128), address VARCHAR2(128), credit_card VARCHAR2(128));
Table created.
SQL> create table myobjects ( cid VARCHAR2(128), owner VARCHAR2(128), balance NUMBER, acct_type VARCHAR2(128));
Table created.
SQL> insert into mytab (cid, owner, address, credit_card) values ('1', 'Bob', '400 Oracle Parkway', '******8118');
insert into mytab (cid, owner, address, credit_card) values ('2', 'Jack', '500 Oracle Parkway', '******7641');
insert into mytab (cid, owner, address, credit_card) values ('3', 'Joe', '600 Oracle Parkway', '******3720');
insert into mytab (cid, owner, address, credit_card) values ('4', 'Tom', '100 Oracle Parkway', '******2873');
insert into myobjects (cid, owner,balance, acct_type) values ('1','DEV1', 400, 'online');
insert into myobjects (cid, owner,balance, acct_type) values ('1', 'DEV1',500, 'in store');
insert into myobjects (cid, owner,balance, acct_type) values ('2', 'DEV2',200, 'online');
insert into myobjects (cid, owner,balance, acct_type) values ('2', 'DEV2',700, 'in store');
insert into myobjects (cid, owner,balance, acct_type) values ('3', 'DEV3',500, 'online');
insert into myobjects (cid, owner,balance, acct_type) values ('3', 'DEV3',900, 'in store');
insert into myobjects (cid, owner,balance, acct_type) values ('4', 'DEV4',1000, 'online');
insert into myobjects (cid, owner,balance, acct_type) values ('4', 'DEV5',1300, 'in store');
SQL> commit;
Commit complete.
接下来我们需要启动Oracle Database 23ai的In Database SQL Firewall功能,这次请使用我们在之前创建的管理用户df_admin。启动In Database SQL Firewall之后,可以通过Select语句检查数据库的In Database SQL Firewall状态。
SQL> conn df_admin/Oracle_4U@freepdb1
Connected.
SQL> exec dbms_sql_firewall.enable;
PL/SQL procedure successfully completed.
SQL> select status from dba_sql_firewall_status;
STATUS
--------
ENABLED
SQL>
In Database SQL Firewall使用的是“白名单”的保护方式,为了方便用户将SQL语句录入到“白名单”当中,Oracle Database 23ai提供了一种便捷的方式,可以使用“捕获SQL”的方式,简单来说就是数据库对特定用户开启SQL捕获功能,在开启该功能之后,该用户发出的SQL语句将被记录下来,当管理员认为需要捕获的SQL语句已经完成时,可以停止数据库的SQL捕获行为。
下面的代码是对dev1用户开启SQL捕获行为,并查看相关状态。
SQL> exec dbms_sql_firewall.create_capture('DEV1');
PL/SQL procedure successfully completed.
SQL> select username,status from dba_sql_firewall_captures;
USERNAME STATUS
---------- --------
DEV1 ENABLED
通过上面结果,我们可以看到dev1用户的SQL捕获已经被开启。接下来将使用dev1用户登录,执行一些查询,来模拟该用户的日常数据库操作。
SQL> conn dev1/Oracle_4U@freepdb1
Connected.
SQL> select count(*) from mytab;
COUNT(*)
----------
4
SQL> select count(*) from myobjects;
COUNT(*)
----------
7
SQL> select distinct owner from mytab;
OWNER
--------------------------------------------------------------------------------
Bob
Jack
Joe
Tom
SQL> select distinct owner from myobjects;
OWNER
--------------------------------------------------------------------------------
DEV1
DEV2
DEV3
DEV4
SQL> select acct_type from myobjects where owner='DEV1';
ACCT_TYPE
--------------------------------------------------------------------------------
online
in store
SQL>
当完成SQL的捕获之后,使用df_admin用户登录,并停止对dev1用户的SQL捕获动作。
SQL> conn df_admin/Oracle_4U@freepdb1
Connected.
SQL> exec dbms_sql_firewall.stop_capture ('DEV1');
PL/SQL procedure successfully completed.
我们可以通过select语句查询刚才的捕获过程中记录下来的相关信息。在下面的查询中,我们可以看到dev1用户在被捕获时使用的IP地址、客户端程序以及操作系统用户,您也可以根据自己的情况,对dba_sql_firewall_session_logs进行查询。
SQL> select username,ip_address,client_program,os_user from dba_sql_firewall_session_logs where username='DEV1';
USERNAME IP_ADDRESS CLIENT_PROGRAM OS_USER
---------- ---------- ------------------------------ ----------
DEV1 10.0.0.10 sqlplus@23ai (TNS V1-V3) oracle
接下来可以查看以下刚才捕获到的SQL语句。
SQL> select sql_text,accessed_objects from dba_sql_firewall_capture_logs where username='DEV1';
SQL_TEXT
--------------------------------------------------------------------------------
ACCESSED_OBJECTS
--------------------------------------------------------------------------------
SELECT COUNT (*) FROM MYTAB
"DEV1"."MYTAB"
SELECT DISTINCT OWNER FROM MYTAB
"DEV1"."MYTAB"
SELECT COUNT (ACCT_TYPE) FROM MYOBJECTS WHERE OWNER=:"SYS_B_0"
"DEV1"."MYOBJECTS"
SQL_TEXT
--------------------------------------------------------------------------------
ACCESSED_OBJECTS
--------------------------------------------------------------------------------
SELECT ACCT_TYPE FROM MYOBJECTS WHERE OWNER=:"SYS_B_0"
"DEV1"."MYOBJECTS"
SELECT DECODE (USER,:"SYS_B_0",XS_SYS_CONTEXT (:"SYS_B_1",:"SYS_B_2"),USER) FROM
SYS.DUAL
"SYS"."DUAL"
SELECT DISTINCT OWNER FROM MYOBJECTS
"DEV1"."MYOBJECTS"
SQL_TEXT
--------------------------------------------------------------------------------
ACCESSED_OBJECTS
--------------------------------------------------------------------------------
SELECT COUNT (*) FROM MYOBJECTS
"DEV1"."MYOBJECTS"
7 rows selected.
接下来通过刚才捕获的SQL语句,生成“允许列表”,在该列表中包含了可以运行的SQL语句以及与查询相关的“路径信息”,比如哪些IP地址可以访问、哪些应用程序可以访问等。换句话说,只有特定的操作系统使用特定的IP地址,并使用特定应用程序才能执行特定的SQL语句,从而可以在更细的粒度上控制SQL的执行。
SQL> EXEC DBMS_SQL_FIREWALL.GENERATE_ALLOW_LIST ('DEV1');
PL/SQL procedure successfully completed.
当“允许列表”被创建之后,可以通过如下select语句查询上面提到的“路径信息”。首先看看哪些SQL语句可以被dev1用户执行。
SQL> SELECT SQL_TEXT FROM DBA_SQL_FIREWALL_ALLOWED_SQL WHERE USERNAME ='DEV1';
SQL_TEXT
--------------------------------------------------------------------------------
SELECT COUNT (*) FROM MYTAB
SELECT DISTINCT OWNER FROM MYTAB
SELECT COUNT (ACCT_TYPE) FROM MYOBJECTS WHERE OWNER=:"SYS_B_0"
SELECT ACCT_TYPE FROM MYOBJECTS WHERE OWNER=:"SYS_B_0"
SELECT DECODE (USER,:"SYS_B_0",XS_SYS_CONTEXT (:"SYS_B_1",:"SYS_B_2"),USER) FROM
SYS.DUAL
SELECT DISTINCT OWNER FROM MYOBJECTS
SELECT COUNT (*) FROM MYOBJECTS
7 rows selected.
下面的select语句可以查询,受信的IP地址。
SQL> select ip_address from dba_sql_firewall_allowed_ip_addr where username='DEV1';
IP_ADDRESS
----------
10.0.0.10
下面的select语句可以查询受信的操作系统用户。
SQL> select os_user from dba_sql_firewall_allowed_os_user where username='DEV1';
OS_USER
----------
oracle
下面的select语句可以查询受信的应用程序。
SQL> select os_program from dba_sql_firewall_allowed_os_prog where username='DEV1';
OS_PROGRAM
--------------------------------------------------------------------------------
sqlplus@23ai (TNS V1-V3)
在确认“允许列表”的信息正确之后,就可以启用该允许列表。但需要注意的是,目前没有启动In Database SQL Firewall的阻止模式,未受信的SQL语句将可以被执行,但会被记录下来,以供日后参考。通过下面查询的BLOCK列值,可以了解当前dev1用户是否启用了阻止模式。
SQL> exec dbms_sql_firewall.enable_allow_list ('DEV1');
PL/SQL procedure successfully completed.
SQL> select username,status,block from dba_sql_firewall_allow_lists;
USERNAME STATUS BLOCK
---------- -------- --------------
DEV1 ENABLED N
接下来我们使用未授信的SQL语句进行测试,因为没有启动阻止模式,因此该SQL语句将可以被执行,但会被记录下来。
SQL> conn dev1/Oracle_4U@freepdb1
Connected.
SQL> update mytab set owner='JOE_BLOGG' where rownum=1;
1 row updated.
SQL> commit;
Commit complete.
您可以通过df_admin用户访问DBA_SQL_FIREWALL_VIOLATIONS数据字典来查询违规执行的SQL语句。
SQL> select username,sql_text,cause,firewall_action from dba_sql_firewall_violations;
USERNAME
----------
SQL_TEXT
--------------------------------------------------------------------------------
CAUSE FIREWAL
----------------- -------
DEV1
UPDATE MYTAB SET OWNER=:"SYS_B_0" WHERE ROWNUM=:"SYS_B_1"
SQL violation Allowed
启用In Database SQL Firewall的阻止模式并查看用户状态。通过下面的查询,可以看到BLOCK的状态由原来的N改为Y。
SQL> conn df_admin/Oracle_4U@freepdb1
Connected.
SQL> exec dbms_sql_firewall.update_allow_list_enforcement ('DEV1',block=>TRUE);
PL/SQL procedure successfully completed.
SQL> select username,status,block from dba_sql_firewall_allow_lists;
USERNAME STATUS BLOCK
---------- -------- --------------
DEV1 ENABLED Y
接下来我们使用dev1用户登录,发出刚才被允许执行的相同违规语句,看看这回是否可以正常被执行。通过下面的结果可以看出,此次的违规语句将被拒绝执行。
SQL> conn dev1/Oracle_4U@freepdb1
Connected.
SQL> update mytab set owner='JOE_BLOGG' where rownum=1;
update mytab set owner='JOE_BLOGG' where rownum=1
*
ERROR at line 1:
ORA-47605: SQL Firewall violation
Help: https://docs.oracle.com/error-help/db/ora-47605/
接下来使用df_admin用户登录,查看系统是否已经记录了刚才的违规查询动作。可以看到第二条记录的firewall_action列值已经是Blocked,表示该语句已经被阻止。
SQL> conn df_admin/Oracle_4U@freepdb1
Connected.
SQL> select username,sql_text,cause,firewall_action from dba_sql_firewall_violations;
USERNAME
----------
SQL_TEXT
--------------------------------------------------------------------------------
CAUSE FIREWAL
----------------- -------
DEV1
UPDATE MYTAB SET OWNER=:"SYS_B_0" WHERE ROWNUM=:"SYS_B_1"
SQL violation Allowed
DEV1
UPDATE MYTAB SET OWNER=:"SYS_B_0" WHERE ROWNUM=:"SYS_B_1"
SQL violation Blocked
接下来我们看看,如果使用了非受信的客户端登录会怎样?本次实验使用sqlcl作为非受信的客户端,该客户端可以免费下载,解压后设定环境变量后即可使用。下面是该客户端的下载及使用方式。本次实验将该工具包下载到/u01下,在下面的环境变量设定中,请根据自己的情况进行修改。
wget https://download.oracle.com/otn_software/java/sqldeveloper/sqlcl-latest.zip
unzip sqlcl-latest.zip
export PATH=$PATH:/u01/sqlcl/bin
sqlcl设定好之后,可以通过它去连接数据库,因为该客户端为非授权客户端,因此连接行为将被阻止。
[oracle@23ai bin]$ sql dev1/Oracle_4U@localhost:1521/FREEPDB1
SQLcl: Release 24.1 Production on Sat Jun 08 04:07:02 2024
Copyright (c) 1982, 2024, Oracle. All rights reserved.
USER = dev1
URL = jdbc:oracle:oci8:@localhost:1521/FREEPDB1
Error Message = ORA-47605: SQL Firewall violation
Help: https://docs.oracle.com/error-help/db/ora-47605/
USER = dev1
URL = jdbc:oracle:thin:@localhost:1521/FREEPDB1
Error Message = ORA-47605: SQL Firewall violation
https://docs.oracle.com/error-help/db/ora-47605/
Username? (RETRYING) ('dev1/*********@localhost:1521/FREEPDB1'?)
USER = dev1
URL = jdbc:oracle:oci8:@localhost:1521/FREEPDB1
Error Message = ORA-47605: SQL Firewall violation
Help: https://docs.oracle.com/error-help/db/ora-47605/
USER = dev1
URL = jdbc:oracle:thin:@localhost:1521/FREEPDB1
Error Message = ORA-47605: SQL Firewall violation
如果想禁用In Database SQL Firewall的拦截行为,可以通过如下语句实现,并通过之前使用过的select语句进行状态确认。
[oracle@23ai bin]$ sqlplus df_admin/Oracle_4U@freepdb1
SQL*Plus: Release 23.0.0.0.0 - Production on Sat Jun 8 04:12:06 2024
Version 23.4.0.24.05
Copyright (c) 1982, 2024, Oracle. All rights reserved.
Last Successful login time: Sat Jun 08 2024 04:00:48 +00:00
Connected to:
Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free
Version 23.4.0.24.05
SQL> exec dbms_sql_firewall.update_allow_list_enforcement ('DEV1',block=>False);
PL/SQL procedure successfully completed.
SQL> select username,status,block from dba_sql_firewall_allow_lists;
USERNAME
--------------------------------------------------------------------------------
STATUS BLOCK
-------- --------------
DEV1
ENABLED N
在今天的内容中为您介绍了Oracle Database 23ai中的In Database SQL Firewall功能及其在数据库安全中的关键作用,展示了通过实时监测和拦截恶意SQL语句,In Database SQL Firewall有效保护数据库的完整性和机密性。通过实验演示了用户管理、表创建、数据插入、In Database SQL Firewall使用与管理、SQL操作捕获与记录、“允许列表”生成及阻止模式测试等步骤,由此可以看出In Database SQL Firewall在防止未授权操作、记录和阻止SQL注入攻击以及处理非受信客户端连接请求方面的有效性,以及在提升数据库安全性和可信度方面的重要性。
我们将在后续的文章中继续为您介绍Oracle Database 23ai的新特性,敬请期待!
编辑:殷海英