数据库安全和最小权限原则
PUBLIC角色隐式授予每位用户。只要为PUBLIC授予任何权限,相应的权限实际上就会授予可以连接到数据库的每个人,创建的每个账户都有权访问这些权限。默认方式下,PUBLIC用户拥有大量权限。
COUNT(*)
----------
28164
gyj@OCM> select table_name from dba_tab_privs where grantee='PUBLIC' and privilege='EXECUTE' and table_name like 'UTL%';
TABLE_NAME
------------------------------
UTL_RAW
UTL_IDENT
UTL_TCP
UTL_HTTP
UTL_FILE
UTL_INADDR
UTL_SMTP
UTL_URL
UTL_ENCODE
UTL_GDK
UTL_COMPRESS
UTL_I18N
UTL_LMS
UTL_NLA_ARRAY_DBL
UTL_NLA_ARRAY_FLT
UTL_NLA_ARRAY_INT
UTL_NLA
UTL_REF
UTL_COLL
UTL_MATCH
UTL_BINARYINPUTSTREAM
UTL_BINARYOUTPUTSTREAM
UTL_CHARACTERINPUTSTREAM
UTL_CHARACTEROUTPUTSTREAM
24 rows selected.
虽然应用软件可以为PUBLIC用户授予执行UTL包的权限,但是我们应当取消PUBLIC用户的这个权限。执行如下操作就可以取消该权限:
Connected.
Revoke succeeded.
UTL_FILE:这个包允许用户读写操作系统,Oracle所有者都可以访问的任何文件和目录,这些文件与目录包括所有的数据库文件以及ORACLE_HOME目录。
二、对安全性至关重要的实例参数
对于数据库的安全性来说,某些实例参数至关重要。这些参数的默认值通常都是合适的,但在某些情况下可能需要修改。
1、UTL_FILE_DIR
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
utl_file_dir string
utl_file_dir默认为空值,设置这个参数需要小心,utl_file_dir参数允许PL/SQL通过UTL_FILE包来访问服务器计算机文件系统。而UTL_FILE包具有打开并读写文件的过程,唯一的限制是Oracle拥有者必须能访问所列出的目录。
utl_file_dir参数接受一个用逗号分隔的目录列表,并且是静态的,如下操作:
System altered.
2、OS_AUTHENT_PREFIX
这个参数控制某个用户是否参够在不需要给出口令的情况下从远程计算机上连接数据库。
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
os_authent_prefix string ops$
remote_os_authent boolean FALSE
(1)修改参数
System altered.
sys@OCM> startup force;
(2)建操作系统用户及设置密码
[root@ocm ~]# passwd joe
Changing password for user joe.
New UNIX password:
BAD PASSWORD: it is WAY too short
Retype new UNIX password:
passwd: all authentication tokens updated successfully.
(3)建数据库用户及授权
sys@OCM> create user joe identified externally;
User created.
sys@OCM> grant dba to joe;
Grant succeeded.
(4)操作系统认证
[joe@ocm ~]$ export ORACLE_BASE=/u01/app/oracle
[joe@ocm ~]$ export ORACLE_HOME=$ORACLE_BASE/product/11.2.0
[joe@ocm ~]$ export ORACLE_SID=ocm
[joe@ocm ~]$ export PATH=$ORACLE_HOME/bin:$PATH
[joe@ocm ~]$ sqlplus /
SQL*Plus: Release 11.2.0.1.0 Production on Mon Mar 11 21:25:13 2013
Copyright (c) 1982, 2009, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
只要服务器操作系统安全,那么上面的操作也是安全的。
3、REMOTE_OS_AUTHENT
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
remote_os_authent boolean FALSE
默认是 FALSE,把它改成TRUE
Connected.
sys@OCM> alter system set remote_os_authent=TRUE scope=spfile;
System altered.
sys@OCM> startup force;
[joe@ocm ~]$ sqlplus /@ocm
SQL*Plus: Release 11.2.0.1.0 Production on Tue Mar 12 19:41:59 2013
Copyright (c) 1982, 2009, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
joe@OCM>
注意这里要想成功操作系统登录,必须把sqlnet.ora给干掉(mv sqlnet.ora sqlnet.ora.bak)
remote_os_authent这个参数开启后, 存在很大的安全隐患, 远端服务器只要根据数据库中存在的外部用户来创建用户, 就可以登陆到数据库中, 因此除非必要, 否则不建议开启这个参数。
4、O7_DICTIONARY_ACCESSIBILITY
O7_DICTIONARY_ACCESSIBILITY实例参数控制使用ANY关键字授予对象权限的效果。这个参数默认为FALSE。
如下操作为用户gyj1授予查看数据库中所有表的权限:
Grant succeeded.
但是,怎么样才能使gyj1能查看所有的数据字典与用户表呢?因为某些表包含了敏感数据据,所以这似乎是不可能的。
O7_DICTIONARY_ACCESSIBILITY参数默认是FALSE,这意味着ANY权限不被授予SYS拥有的对象,从而保护了数据字典,此时gyj1能够查看所有的用护数据。但是无法查看SYS拥有的对象。如果将这个参数改为TRUE,那么意味着所有对象都被授予了ANY权限,此时gyj1能够查看数据字典以及所有用户的数据。
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
O7_DICTIONARY_ACCESSIBILITY boolean FALSE
当O7_DICTIONARY_ACCESSIBILITY为FALSE,想要访问数据字典如下授权操作:
Grant succeeded.
sys@OCM> conn gyj1/gyj1
Connected.
COUNT(*)
----------
2907
gyj1@OCM> conn /as sysdba
Connected.
Revoke succeeded.
sys@OCM> grant select any table to gyj1;
Grant succeeded.
sys@OCM> conn gyj1/gyj1
Connected.
select count(*) from sys.tab$
*
ERROR at line 1:
ORA-00942: table or view does not exist
当O7_DICTIONARY_ACCESSIBILITY为FALSE,想要访问数据字典可以把O7_DICTIONARY_ACCESSIBILITY改为TRUE。
Connected.
System altered.
sys@OCM> startup force;
ORACLE instance started.Total System Global Area 836976640 bytes
Fixed Size 1339740 bytes
Variable Size 419434148 bytes
Database Buffers 411041792 bytes
Redo Buffers 5160960 bytes
Database mounted.
Database opened.
sys@OCM> conn gyj1/gyj1
Connected.
gyj1@OCM> select count(*) from sys.tab$;
COUNT(*)
----------
2907
5、REMOTE_LOGIN_PASSWORFILE
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
remote_login_passwordfile string EXCLUSIVE
将remote_login_passwordfile设为EXCLUSIVE或SHARED时,用户可以通过列不同的方法得到SYSDBA连接:
SHARED:在同一个Oracle主目录内运行的所有实例共享一个公有的口令文件,对于所有实例公有的SYS用户来说,这个主目录只有一个口令。
EXCLUSIVE:实例会寻找一个其名称包含实例名的文件(在windows中为:PWD<SID>.ora,在UNIX中为orapwd<SID>),这个文件具有实例特有的口令。
USERNAME SYSDB SYSOP SYSAS
------------------------------ ----- ----- -----
SYS TRUE TRUE FALSE
GYJ1 TRUE FALSE FALSE
sys@OCM> grant sysoper to hr;
Grant succeeded.
sys@OCM> grant sysdba to gyj;
Grant succeeded.
sys@OCM> select * from v$pwfile_users;
USERNAME SYSDB SYSOP SYSAS
------------------------------ ----- ----- -----
SYS TRUE TRUE FALSE
GYJ1 TRUE FALSE FALSE
HR FALSE TRUE FALSE
GYJ TRUE FALSE FALSE
三、使用标准数据库审核
无论安全策略多么完善,总是存在策略显得不足的情况。
除了SYSDBA审核之外,Oracle还提供了三种审核技术:数据库审核、基于值的审核、细粒度审核。
实例参数AUDIT_SYS_OPERATIONS设置为TRUE(默认FALSE)
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
audit_sys_operations boolean FALSE
2、数据库审核:能够跟踪特定权限的使用、特定命令的执行、对于特定表的访问能及登录尝试。
(1)设置数据库审核之前,必须设置audit_trail实例参数。这个参数具体有以下值:
NONE(或者FALSE):无论试图配置哪一种审核,这个参数值会禁用数据库审核。
OS:审核记录会被写至操作系统的审核跟踪(也就是Windows系统中的Windows Application Log文件夹或者Unix系统中的AUDIT_FILE_DEST目录)
DB:审核记录会被写入数据字典表SYS.AUD$。我们可以通过某些视图来查看这个表的内容。
DB_EXTENDED:与DB的作用大体相同,不过包含生成审核记录的、具有绑定变量的SQL语句。
XML:与OS的作用大体相同,但使用XML标记设置生成。
XML_EXTENDED:与XML的作用大体相同,但使用SQL语句和绑定变量。
(2)查看audit_trail参数的值,默认值为:DB
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
audit_trail string DB
(3)使用AUDIT命令配置数据库审核。
使用如下命令可以审核对表的查询
Audit succeeded.
gyj@OCM> SELECT * FROM HR.DEPARTMENTS;
DEPARTMENT_ID DEPARTMENT_NAME MANAGER_ID LOCATION_ID
------------- ------------------------------ ---------- -----------
300 DBA1 100 1000
400 DBA2 1000
500 DBA3 1000
3 rows selected.
gyj@OCM> select timestamp, USERNAME,owner,obj_name,SES_ACTIONS from dba_audit_trail where OBJ_NAME='DEPARTMENTS';
TIMESTAMP USERNAME OWNER OBJ_NAME SES_ACTIONS
-------------- ------------------------------ ------------------------------ -------------------------------------------------------------------------------------------------------------------------------- -------------------
10-03 -13 GYJ HR DEPARTMENTS ---------S------
使用如下命令可以审核权限的命用
Audit succeeded.
sys@OCM> audit select any table by session;
Audit succeeded.
默认方式下,审核会为违返审核条件的每个会话生成一个审核记录,而不考虑违反条件的次数。这相当于为AUDIT命令追加了关键字BY SESSION。
为AUDIT命令追加关键字BY ACCESS时,会为每次违反条件的情况生成一条记录。
使用如下命令可以审核对象
Audit succeeded.
只要会话在指定表中插入一行就会生成审核记录。WHENEVER SUCCESSFUL关键字将审核记录限制为操作成功的记录,WHENEVER NOT SUCCESSFUL是替换语法。默认方式下,会审核所有操作。
Audit succeeded.
DBA_AUDIT_TRAIL视图是一个很重要的视图,其它审核视图(DBA_AUDIT_OBJECT、DBA_AUDIT_STATEMENT、DBA_AUDIT_SESSION)都是DBA_AUDIT_TRAIL视图的一个子集,仅显示与相关的某些审核记录和列。
3、基于值的审核:使用了数据库触发器。在插入、更新或删除记录时,就会运行一个包括记录事件全部细节的pl/sql代码块。
前面所描述的数据库审核可以捕获到针对某个表执行一条命令的事实,但是没有跟踪受影响的行。例如,如果执行AUDIT INSERT ON GYJ.T10命令,只要在指定表中插入一行就会生成一条审核记录,但是该审核记录不会包含插入行的实际值。有些时侯,我们希望捕获这些实际值地,此时就需要使用数据库触发器。
gyj@OCM> create table t1 (id int,name varchar2(100));
Table created.
gyj@OCM> insert into t1 values(1,'Joe');
1 row created.
gyj@OCM> insert into t1 values(2,'Tom');
1 row created.
gyj@OCM> insert into t1 values(3,'Rose');
1 row created.
gyj@OCM> insert into t1 values(4,'Jack');
1 row created.
gyj@OCM> insert into t1 values(5,'jemmy');
1 row created.
gyj@OCM> commit;
Commit complete.
gyj@OCM> create table t_audit (os_user varchar2(20),ip_address varchar2(20),change varchar2(100));
Table created.
创建触发器语句,操作如下:
gyj@OCM> CREATE OR REPLACE TRIGGER gyj.name_audit
2 AFTER UPDATE OF name
3 ON gyj.t1
4 REFERENCING NEW AS NEW OLD AS OLD
5 FOR EACH ROW
6 BEGIN
7 IF :old.name != :new.name THEN
8 INSERT INTO gyj.t_audit
9 VALUES(sys_context('userenv','os_user'),sys_context('userenv','ip_address'),:new.id||' name changed from '||:old.name||' to '||:new.name);
10 END IF;
11 END;
12 /
gyj@OCM> update t1 set name='guoyJoe' where name='Joe';
1 row updated.
gyj@OCM> update t1 set name='Tony' where id=2;
1 row updated.
gyj@OCM> update t1 set name='coco' where id=3;
1 row updated.
gyj@OCM> select * from t_audit;
OS_USER IP_ADDRESS CHANGE
---------- ------------------ ---------------------------------------
oracle 1 name changed from Joe to guoyJoe
oracle 2 name changed from Tom to Tony
oracle 3 name changed from Rose to coco
4、细粒度审核:允计根据所访问的记录(或该记录的列)来跟踪对表的访问。与数据库审核或基于值的审核相比,细粒度审核更为精确,并且可以将生成的审核记录的范围限制为感兴趣的审核记录。
(1)创建GYJ_EMP1,此策略将捕获读取的条件是:SELECT中出现SALARY, COMMISSION_PCT或WHERE条件中出现SALARY 列不为空和 COMMISSION_PCT 列不为空的所有SELECT的语句。(注只要SALARY, COMMISSION_PCT两列出现在SELECT或WHERE中就审计)
操作如下:
sys@OCM> conn hr/hr
Connected.
hr@OCM> BEGIN
2 DBMS_FGA.ADD_POLICY(
3 object_schema => 'HR',
4 object_name => 'EMPLOYEES',
5 policy_name => 'GYJ_EMP1',
6 audit_condition => 'SALARY IS NOT NULL AND COMMISSION_PCT IS NOT NULL',
7 audit_column => 'SALARY,COMMISSION_PCT',
8 enable => TRUE,
9 statement_types => 'SELECT',
10 audit_trail => DBMS_FGA.DB_EXTENDED,
11 audit_column_opts => DBMS_FGA.ALL_COLUMNS);
12 END ;
13 /
PL/SQL procedure successfully completed.
hr@OCM> col AUDIT_TYPE for a20
hr@OCM> col DB_USER for a10
hr@OCM> col OS_USER for a10
hr@OCM> col USERHOST for a10
hr@OCM> col OBJECT_SCHEMA for a10
hr@OCM> col OBJECT_NAME for a10
hr@OCM> col ACTION for a10
hr@OCM> col SQL_TEXT for a100
hr@OCM> select AUDIT_TYPE ,SESSION_ID,DB_USER,OS_USER,USERHOST,OBJECT_SCHEMA,OBJECT_NAME,ACTION,sql_text from DBA_COMMON_AUDIT_TRAIL where sql_text like '%EMP%';
AUDIT_TYPE SESSION_ID DB_USER OS_USER USERHOST OBJECT_SCH OBJECT_NAM ACTION SQL_TEXT
-------------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------------------------------------------------------------------------------------------------
Fine Grained Audit 470672 HR oracle ocm HR EMPLOYEES select * from EMPLOYEES where SALARY IS NOT NULL AND COMMISSION_PCT IS NOT NULL
Fine Grained Audit 470672 HR oracle ocm HR EMPLOYEES select * from EMPLOYEES
Fine Grained Audit 470672 HR oracle ocm HR EMPLOYEES select * from EMPLOYEES WHERE SALARY IS NOT NULL
Fine Grained Audit 470672 HR oracle ocm HR EMPLOYEES select * from EMPLOYEES WHERE SALARY >5000
Fine Grained Audit 470672 HR oracle ocm HR EMPLOYEES select employee_id from EMPLOYEES WHERE SALARY IS NOT NULL AND COMMISSION_PCT IS NOT NULL
hr@OCM> SELECT SQL_TEXT FROM DBA_FGA_AUDIT_TRAIL WHERE sql_text like '%EMP%';
SQL_TEXT
----------------------------------------------------------------------------------------------------
select * from EMPLOYEES where SALARY IS NOT NULL AND COMMISSION_PCT IS NOT NULL
select * from EMPLOYEES
select * from EMPLOYEES
select * from EMPLOYEES WHERE SALARY IS NOT NULL
select * from EMPLOYEES WHERE SALARY >5000
select employee_id from EMPLOYEES WHERE SALARY IS NOT NULL AND COMMISSION_PCT IS NOT NULL
select COMMISSION_PCT from EMPLOYEES WHERE SALARY IS NOT NULL
(2)审计EMP1表中EMPNO,MGRNO,SALARY这三列的DML操作,不审计列EMPNAME
于是我创建了个审计如下:
hr@OCM> create table EMP1 AS SELECT EMPLOYEE_ID EMPNO,LAST_NAME EMPNAME,MANAGER_ID MGRNO,SALARY FROM EMPLOYEES;
Table created.
hr@OCM> begin
2 dbms_fga.add_policy(object_schema => 'HR',
3 object_name => 'EMP1',
4 policy_name => 'FGA_EMP',
5 audit_column => 'EMPNO,MGRNO,SALARY',
6 statement_types =>'insert,update,delete');
7 end;
8 /
PL/SQL procedure successfully completed.
hr@OCM> SELECT SQL_TEXT FROM DBA_FGA_AUDIT_TRAIL WHERE sql_text like '%emp1%';
SQL_TEXT
----------------------------------------------------------------------------------------------------
update emp1 set EMPNAME='Joe' where empno=100
可是,对于下面这个update也作了审计:update emp1 set EMPNAME='Joe' where empno=100;
像这样的update有很多,如果都审计了sys.fga_log$表扩展太快,请问大家有什么办法能让审计对于EMPNAME的DML操作都不审计呢?
解决办法:分别建两个策略
A)策略一对insert和delete操作的列是:EMPNO,MGRNO,SALARY。
hr@OCM> begin
2 dbms_fga.add_policy(object_schema => 'HR',
3 object_name => 'EMP1',
4 policy_name => 'FGA_EMP1',
5 audit_column => 'EMPNO,MGRNO,SALARY',
6 statement_types =>'insert,delete');
7 end;
8 /
PL/SQL procedure successfully completed.
B)策略二对update操作的列是:MGRNO,SALARY,不包括了EMPNO。
hr@OCM> begin
2 dbms_fga.add_policy(object_schema => 'HR',
3 object_name => 'EMP1',
4 policy_name => 'FGA_EMP2',
5 audit_column => 'MGRNO,SALARY',
6 statement_types =>'update');
7 end;
8 /
PL/SQL procedure successfully completed.
先drop掉原来的FGA_EMP策略:
hr@OCM> BEGIN
2 DBMS_FGA.DROP_POLICY(
3 object_schema => 'HR',
4 object_name => 'EMP1',
5 policy_name => 'FGA_EMP');
6 END ;
7 /
PL/SQL procedure successfully completed.
再对雇员名称做update测试:
hr@OCM> update emp1 set EMPNAME='gyj1' where empno=130;
1 row updated.
查审计记录:
hr@OCM> SELECT SQL_TEXT FROM DBA_FGA_AUDIT_TRAIL WHERE sql_text like '%emp1%';
SQL_TEXT
----------------------------------------------------------------------------------------------------
update emp1 set EMPNAME='Joe' where empno=100
没有发现update emp1 set EMPNAME='gyj1' where empno=130;的语句被审计了!!!
**********本博客所有内容均为原创,如有转载请注明作者和出处!!!**********
Name: guoyJoe
QQ: 252803295
Email: oracledba_cn@hotmail.com
Blog: http://blog.csdn.net/guoyJoe
ITPUB: http://www.itpub.net/space-uid-28460966.html
OCM: http://education.oracle.com/education/otn/YGuo.HTM
_____________________________________________________________
加群验证问题:哪些SGA结构是必需的,哪些是可选的?否则拒绝申请!!!
答案在:http://blog.csdn.net/guoyjoe/article/details/8624392
Oracle@Paradise 总群:127149411
Oracle@Paradise No.1群:177089463(已满)
Oracle@Paradise No.2群:121341761
Oracle@Paradise No.3群:140856036