In order to avoid the necessity for users to provide usernames and passwords twice once for the operating system logon, and again for the database logon, it was common to create the Orac
Trang 1are static: you must restart the instance for a change to take effect This is intended to provide extra security, as it reduces the likelihood that they can be changed temporarily
to an inappropriate setting without the DBA being aware of it
UTL_FILE_DIR
The UTL_FILE_DIR instance parameter defaults to NULL and is therefore not a security problem But if you need to set it, take care This parameter gives PL/SQL access to the file system of the server machine, through the UTL_FILE supplied
package The package has procedures to open a file (either a new file or an existing one) and read from and write to it The only limitation is that the directories listed must be accessible to the Oracle owner
The difficulty with this parameter is that, being set at the instance level, it offers
no way to allow some users access to some directories and other users access to other directories All users with execute permission on the UTL_FILE package have access to all the directories listed in the UTL_FILE_DIR parameter
The parameter takes a comma-separated list of directories and is static To set it, follow the syntax in this example, which gives access to two directories, and restart the instance:
SQL> alter system set utl_file_dir='/oracle/tmp','/oracle/interface' scope=spfile;
TIP The UTL_FILE_DIR parameter can include wildcards Never set it to ‘*’,
because that will allow all users access to everything that the database owner can see, including the ORACLE_HOME and all the database files
REMOTE_OS_AUTHENT and OS_AUTHENT_PREFIX
The REMOTE_OS_AUTHENT instance parameter defaults to FALSE This controls whether a user can connect to the database from a remote computer without the need
to supply a password The reasons for wanting to do this have largely disappeared with modern computer systems, but the capability is still there
In the days before all users had intelligent terminals, such as PCs, it was customary for users to log on directly to the database server machine and therefore to be authenticated
by the server’s operating system They would then launch their user process on the server machine and connect to the database In order to avoid the necessity for users
to provide usernames and passwords twice (once for the operating system logon, and again for the database logon), it was common to create the Oracle users with this syntax:
SQL> create user jon identified externally;
This delegates responsibility for authentication to the server’s operating system Any person logged on to the server machine as operating system user “jon” will be able to connect to the database without the need for any further authentication:
$ sqlplus /
Connected to:
Trang 2SQL> show user;
USER is "JON”
SQL>
This is secure, as long as your server’s operating system is secure As networking
became more widespread, it became common to separate the user process workload
from the server process workload by having users log on to a different machine
dedicated to running user processes, which would connect to the server over Oracle
Net (or SQL*Net, as it was then known) Since the user no longer logs on to the
server’s operating system, external authentication can’t be used—unless you use the
REMOTE_OS_AUTHENT parameter Setting this to TRUE means that user JON can
connect without a password from any machine where he is logged on as operating
system user “jon” An example of the syntax is
sqlplus connect /@orcl11g
This will log the user on to the database identified in the connect string ORCL11G,
passing through his operating system username on his local machine as the database
username This is only secure if you trust the operating systems of all machines
connected to the network An obvious danger is PCs: it is common for users to have
administration rights on their PCs, and they can therefore create user accounts that
match any Oracle account name
TIP It is generally considered bad practice to enable remote operating system
authentication
The OS_AUTHENT_PREFIX instance parameter is related to external authentication,
either local or remote It specifies a prefix that must be applied to the operating system
username before it can be mapped onto an Oracle username The default is “OPS$”
In the preceding example, it is assumed that this parameter has been cleared, with
SQL> alter system set os_authent_prefix='' scope=spfile;
Otherwise, the Oracle username would have had to be OPS$JON
O7_DICTIONARY_ACCESSIBILITY
The O7_DICTIONARY_ACCESSIBILITY instance parameter controls the effect of
granting object privileges with the ANY keyword It defaults to FALSE You can give
user JON permission to see any table in the database with
SQL> grant select any table to jon;
but do you want him to be able to see the data dictionary tables as well as user tables?
Probably not—some of them contain sensitive data, such as unencrypted passwords
or source code that should be protected
O7_DICTIONARY_ACCESSIBILITY defaults to false, meaning that the ANY
privileges exclude objects owned by SYS, thus protecting the data dictionary; JON
Trang 3can see all the user data, but not objects owned by SYS If you change the parameter
to TRUE, then ANY really does mean ANY—and JON will be able to see the data dictionary as well as all user data
It is possible that some older application software may assume that the ANY privileges include the data dictionary, as was always the case with release 7 of the Oracle database (hence the name of the parameter) If so, you have no choice but to change the parameter to TRUE until the software is patched up to current standards
TIP Data dictionary accessibility is sometimes a problem for application
installation routines You may have to set O7_DICTIONARY_ACCESSIBILITY
to TRUE while installing a product, and then put it back on default when the installation is finished
If you have users who really do need access to the data dictionary, rather than setting O7_DICTIONARY_ACCESSIBILITY to true, consider granting them the SELECT ANY DICTIONARY privilege This will let them see the data dictionary and dynamic performance views, but they will not be able to see any user data—unless you have specifically granted them permission to do so This might apply, for example, to the staff of an external company you use for database administration support: they need access to all the data dictionary information, but they have no need to view your application data
REMOTE_LOGIN_PASSWORDFILE
The remote REMOTE_LOGIN_PASSWORDFILE instance parameter controls whether it
is possible to connect to the instance as a user with the SYSDBA or SYSOPER privilege over the network With this parameter on its default of NONE, the only way to get a SYSDBA connection is to log on to the operating system of the server machine as a member of the operating system group that owns the Oracle software This is absolutely secure—as long as your server operating system is secure, which it should be
Setting this parameter to either EXCLUSIVE or SHARED gives users another way in: even if they are not logged on to the server as a member of the Oracle owning group, or even if they are coming in across the network, they can still connect as SYSDBA if they know the appropriate password The passwords are embedded, in encrypted form, in an operating system file in the Oracle home directory: $ORACLE_ HOME/dbs on Unix, or %ORACLE_HOME%\database on Windows A setting of SHARED means that all instances running of the same Oracle home directory will share a common password file This will have just one password within it for the SYS user that is common to all the instances EXCLUSIVE means that the instance will
look for a file whose name includes the instance name: PWDinstance_name.ora
on Windows, orapwinstance_name on Unix, where instance_name is the
instance name This file will have instance-specific passwords
Trang 4Create the password file by running the orapwd utility from an operating system
prompt This will create the file and embed within it a password for the SYS user
Subsequently, you can add other users’ passwords to the file, thus allowing them to
connect as SYSDBA or SYSOPER as well Review the scripts in Chapter 2 for an example
of the syntax for creating a password file To add another user to the file, grant them
either the SYSDBA or SYSOPER privilege, as in Figure 6-10 The V$PWFILE_USERS
view shows you which users have their passwords entered in the password file, and
whether they have the SYSOPER privilege, the SYSDBA privilege, or both
Note that when connecting as SYSDBA, even though you use a username and
password, you end up connected as user SYS; when connecting as SYSOPER, you
are in fact connected as the PUBLIC user
Enabling a password file does not improve security; it weakens it, by giving users
another way of obtaining a privileged connection (in addition to local operating
system authentication, which is always available) It is, however, standard practice
to enable it, because without a password file it may be very difficult to manage the
database remotely
TIP Some computer auditors do not understand operating system and
password file authentication They may even state that you must create a
password file, to improve security Just do as they say—it is easier than arguing
Figure 6-10 Managing the password file with SQL*Plus
Trang 5Exercise 6-5: Remove Some Potentially Dangerous Privileges In this exercise, you will generate a script that could be used (possibly after edits, depending
on local requirements) to remove some of the more dangerous privileges from PUBLIC Use SQL*Plus
1 Connect to your database as user SYSTEM
2 Adjust SQL*Plus to remove extraneous characters from its output:
set heading off set pagesize 0 set feedback off
3 Start spooling output to a file in a suitable directory Following are examples for Unix and Windows:
spool $HOME/oracle/scripts/clear_public_privs.sql spool c:\oracle\scripts\clear_public_privs.sql
4 Generate the SQL command file by running this statement:
select 'revoke execute on '||table_name||' from public;' from dba_tab_privs where table_name like 'UTL_%';
5 Stop the spooling of output:
spool off
6 Open the generated file with the editor of your choice Note that you need to remove the first and last lines before running the script Site variations would determine which (if any) privileges could not actually be revoked
Work with Standard Database Auditing
No matter how good your security policies are, there will be occasions when a policy
is not enough You will have to accept that users have privileges that could be dangerous All you can do is monitor their use of those privileges, and track what they are actually doing with them The most extreme example of this is you—the database administrator Anyone with the SYSDBA privilege can do anything at all within the database For your employers to have confidence that you are not abusing this power (which cannot
be revoked, or you couldn’t do your job), it is necessary to audit all SYSDBA activity For regular users, you may also wish to track what they doing You may not be able to prevent them from breaking company rules on access to data, but you can track the fact that they did it
Apart from SYSDBA auditing, Oracle provides three auditing techniques:
• Database auditing can track the use of certain privileges, the execution of certain commands, access to certain tables, or logon attempts
• Value-based auditing uses database triggers Whenever a row is inserted, updated, or deleted, a block of PL/SQL code will run that can (among other things) record complete details of the event
Trang 6• Fine-grained auditing allows tracking access to tables according to which rows
(or which columns of the rows) were accessed It is much more precise than
either database auditing or value-based auditing, and it can limit the number
of audit records generated to only those of interest
TIP Auditing of any type increases the amount of work that the database
must do In order to limit this workload, you should focus your auditing
closely and not track events of minimal significance
Auditing SYSDBA Activity
If the instance parameter AUDIT_SYS_OPERATIONS is set to TRUE (the default is
FALSE), then every statement issued by a user connected AS SYSDBA or AS SYSOPER
is written out to the operating system’s audit trail This contains a complete record of
all work done by the DBA Clearly, the audit trail must be protected; if it were possible
for the DBA to delete the audit records, there would be no point in creating them
This brings up the question of separation of duties Your system needs to be configured
in such a way that the DBA has no access to the audit records that track their activity;
they should only be accessible to the computer’s system administrator If the DBA is
also the system administrator, then the auditing is useless For this reason, a decent
computer auditor will always state that the DBA must not have the Unix “root”
password (or the Windows “Administrator” password)
The destination of the SYS audit records is platform specific On Windows, it is the
Windows Application log, on Unix it is controlled by the AUDIT_FILE_DEST parameter
This parameter should point to a directory on which the Oracle owner has write
permission (so that the audit records can be written by the instance) but that the Unix
ID used by the DBA does not, so that they cannot adjust the audit records by hand
Database Auditing
Before setting up database auditing, the AUDIT_TRAIL instance parameter must be
set This has six possible values:
• NONE (or FALSE) Database auditing is disabled, no matter what auditing
you attempt to configure
• OS Audit records will be written to the operating system’s audit trail—the
Application Log on Windows, or the AUDIT_FILE_DEST directory on Unix
• DB The audit records are written to a data dictionary table, SYS.AUD$ There
are views that let you see the contents of this table
• DB_EXTENDED As DB, but including the SQL statements with bind
variables that generated the audit records
• XML As OS, but formatted with XML tags.
• XML_EXTENDED As XML, but with the SQL statements and bind variables.
Trang 7Having set the AUDIT_TRAIL parameter, you can use database auditing to capture login attempts, use of system and object privileges, and execution of SQL commands Furthermore, you can specify whether to audit these events when they succeeded, when they failed because of insufficient privileges, or both Auditing commands that did not succeed can be particularly valuable: any records produced will tell you that users are attempting to break their access rights
Database auditing is configured using the AUDIT command
Use of privileges can be audited with, for example,
SQL> audit create any trigger;
SQL> audit select any table by session;
Your programmers will have been granted the CREATE ANY TRIGGER privilege because they will be creating triggers on other schemas’ tables as part of their work, but it is a dangerous privilege that could be used maliciously So you certainly need to know when they use it, in order that you can demand to see the code Similarly, some staff will need the SELECT ANY TABLE and UPDATE ANY TABLE privileges in order
to sort out problems with transactions that have gone wrong, but whenever they use these privileges, a record must be kept so that they will be deterred from accessing data unless they have a legitimate reason
By default, auditing will generate one audit record for every session that violates
an audit condition, irrespective of the number of times it violates the condition This
is equivalent to appending BY SESSION to the AUDIT command Appending the keywords BY ACCESS to the AUDIT command will generate one record for every violation
TIP The default BY SESSION clause will often not be what you want, but it
does reduce the volume of audit records produced to a more manageable number
Auditing can also be oriented toward objects:
SQL> audit insert on ar.hz_parties whenever successful;
SQL> audit all on ar.ra_interface_lines_all;
The first of these commands will generate audit records if a session inserts a row into the named table The WHENEVER SUCCESSFUL keywords restrict audit records
to those where the operation succeeded; the alternative syntax is WHENEVER NOT SUCCESSFUL By default, all operations (successful or not) are audited The second example will audit every session that executes and SELECT, DML, or DDL statements against the named table
Database Control has a graphical interface to the auditing system Figure 6-11 shows the interface after executing the two preceding commands Note that the window has tabs for displaying, adding, and removing auditing of privileges, objects, and statements In the figure, you can see the auditing of objects owned by user AR
In the Configuration section of the window shown in Figure 6-11, there are links for setting the audit parameter previously described
Trang 8Logons are audited with AUDIT SESSION For example,
SQL> audit session whenever not successful;
This is equivalent to auditing the use of the CREATE SESSION privilege Session
auditing records each connection to the database The NOT SUCCESFUL keywords
restrict the output to only failed attempts This can be particularly useful: recording
failures may indicate if attempts are being made to break into the database
If auditing is to the operating system (because the AUDIT_TRAIL instance
parameter is set to OS or XML), then view the files created in the operating system
audit trail to see the results of the audits with an appropriate editor If auditing is
directed to the database (AUDIT_TRAIL=DB or DB_EXTENDED), then the audit
records are written to a table in the data dictionary: the SYS.AUD$ table It is possible
to query this directly, but usually you will go through views The critical view is the
DBA_AUDIT_TRAIL view This will show all audit trail entries, no matter whether the
audited event was use of a privilege, execution of a statement, or access to an object
Of necessity, the view is very generic, and not all columns (41 in all) will be populated
for each audit trail entry Table 6-1 lists the more commonly used columns
Figure 6-11 Managing standard auditing with Database Control
Trang 9The other audit views (DBA_AUDIT_OBJECT, DBA_AUDIT_STATEMENT, and DBA_AUDIT_SESSION) each show a subset of the DBA_AUDIT_TRAIL view, only displaying certain audit records and the columns relevant to them
Value-Based Auditing with Triggers
The database auditing just described can catch the fact that a command was executed against a table, but not necessarily the rows that were affected For example, issuing AUDIT INSERT ON HR.EMPLOYEES will cause an audit record to be generated whenever a row is inserted into the named table, but the record will not include the actual values of the row that was inserted On occasion, you may want to capture these This can be done by using database triggers
A database trigger is a block of PL/SQL code that will run automatically whenever
an INSERT, UPDATE, or DELETE is executed against a table A trigger can do almost anything—in particular, it can write out rows to other tables These rows will be part
of the transaction that caused the trigger to execute, and they will be committed when the rest of the transaction is committed There is no way that a user can prevent the trigger from firing: if you update a table with an update trigger defined, that trigger will execute
Consider this trigger creation statement:
SQL> CREATE OR REPLACE TRIGGER system.creditrating_audit
2 AFTER UPDATE OF creditrating
3 ON store.customers
4 REFERENCING NEW AS NEW OLD AS OLD
5 FOR EACH ROW
6 BEGIN
7 IF :old.creditrating != :new.creditrating THEN
8 INSERT INTO system.creditrating_audit
9 VALUES (sys_context('userenv','os_user'),
10 sys_context(‘userenv','ip_address'),
11 :new.customer_id ||' credit rating changed from
12 '||:old.creditrating||
13 ' to '||:new.creditrating);
14 END IF;
15 END;
Column Description
Table 6-1 Common Columns in the DBA_AUDIT_TRAIL View
Trang 10The first line names the trigger, which is in the SYSTEM schema Lines 2 and 3 specify
the rule that determines when the trigger will execute: every time the CREDITRATING
column of a row in STORE’s CUSTOMERS table is updated There could be separate
triggers defined to manage inserts and deletes, or actions on other columns Line 7
supplies a condition: if the CREDITRATING column were not actually changed, then
the trigger will exit without doing anything But if the CREDITRATING column were
updated, then a row is inserted into another table designed for trapping audit events
Lines 9 and 10 use the SYS_CONTEXT function to record the user’s operating system user
name and the IP address of the terminal in use when the update is executed Lines 11, 12,
and 13 record the customer number of the row updated, and the old and new values of
the CREDITRATING column Database auditing as described in the preceding section
could have captured all this information, except for the actual values: which customer
was updated, and what the data change actually was
TIP Auditing through triggers is a slower process than database auditing,
but it does give you more information and let you implement sophisticated
business rules
Fine-Grained Auditing (FGA)
Database auditing can record all statement accesses to a table, whether SELECT or for
DML But it cannot distinguish between rows, even though it might well be that only
some rows contain sensitive information Using database auditing, you may have to
sift through a vast number of audit records to find the few that have significance
Fine-grained auditing, or FGA, can be configured to generate audit records only when
certain rows are accessed, or when certain columns of certain rows are accessed It can
also run a block of PL/SQL code when the audit condition is breached
FGA is configured with the package DBMS_FGA To create an FGA audit policy,
use the ADD_POLICY procedure, which takes these arguments:
defaults to the user who is creating the policy.
record If left NULL, access to any row is audited.
column is audited.
condition is met The default is the user who is creating the policy.
disabled with the DISABLE_POLICY procedure If FALSE, then the ENABLE_POLICY procedure must be used to activate the policy.