Download ALTER DATABASE ADD SECURITY

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Microsoft Access wikipedia , lookup

Concurrency control wikipedia , lookup

Database wikipedia , lookup

Microsoft SQL Server wikipedia , lookup

SQL wikipedia , lookup

Microsoft Jet Database Engine wikipedia , lookup

Relational model wikipedia , lookup

Open Database Connectivity wikipedia , lookup

Database model wikipedia , lookup

Clusterpoint wikipedia , lookup

PL/SQL wikipedia , lookup

Oracle Database wikipedia , lookup

Transcript
DBA
Reviewed by Oracle Certified Master Korea Community
( http://www.ocmkorea.com http://cafe.daum.net/oraclemanager )
ALTER DATABASE ADD SECURITY;
INTRODUCTION
Security has recently become a much more significant portion of the typical database administrator’s life. This additional
burden on what is usually an already over-worked staff often insures that database and data security, while “considered a
priority” by management, are often minimal. The reality is that even a well-intentioned and fairly security-aware organization is
likely to consider any availability, performance, and application enhancement activities more critical than even the most basic
security-related activities.
As with any such activity, there are some basic tenets that hold true with regard to data and database security. One of the most
important is that “an ounce of prevention is worth a ton of cure”. While prevention is important, detection is essential. If
something bad is happening, it is critical to find out as soon as possible.
This sort of security is not the exclusive domain of the DBA. The database is only as secure as the host on which it resides.
Database and host security may be seriously compromised by lapses in network security. Data security is extremely dependent
on the security of the application - and this is often the weakest link. Developers and development managers sometimes have
the mistaken notion that security is something that can be applied by the DBA, like a coat of varnish, after application design
and development are complete. Data security considerations should be an integral part of analysis and design.
The intent of this paper is to help efforts towards serious database security “get off the ground”. The scope is essentially a set
of common denominator topics of interest to the typical Oracle DBA, although some application design topics and particularly
problematic issues of a more advanced nature are mentioned in passing.
The Center for Internet Security (CIS) has established two levels for Oracle security issues. Level one recommendations are
deemed to be those, which are unlikely to break anything, and can be implemented by any Oracle DBA. Level two issues are
those, which are more likely to break something, or may require a more advanced DBA to implement. The majority of the
topics discussed here are from level one.
The number of potential issues may seem overwhelming at first. In developing an action plan to harden the database and
related components, the suggestion is to prioritize the actions based on the severity of the vulnerability they reduce or
eliminate and on the impact they may have. Some tasks, such as password-protecting the Oracle listener, can improve security
without any significant risk or notable impact on the system. Others may only be practical on new systems, applications in the
early design phase or with major changes to the database, application or system.
DISCLAIMER
It should be noted that some of the suggestions here might seem to contradict the recommendations of CIS and other such
entities. In most cases, these exceptions are noted and explained. Any controversial content in this paper is the opinion of the
author, not necessarily that of the Center for Internet Security, Solutionary, or any other entity.
This paper is not intended to be comprehensive or complete. Any one of the topics discussed here could be, and usually is,
the sole focus of a much more detailed paper. Where appropriate, and the reference is known and publicly available, such
resources are noted. There are a number of database security topics not discussed here at all. The subject is broad, research is
ongoing, the Oracle software is ever changing, and the environment in which the database lives is variable. No outside party
will know your applications, your organization and the constraints they may imply as well as you. Hopefully though, this will
serve as a set of general guidelines and provide motivation to investigate further into the security specifics relevant to the
reader.
-1-
Paper #537
DBA
SOURCES OF TROUBLE
There are many possible modes of attack on an Oracle database and many ways to classify them. Here, we will consider…
MALICIOUS ATTACKS
Someone may intentionally try to access your database with the intent of doing some sort of damage. These attacks may come
from either inside or outside the organization.
The motivation for this type of attack may be financial gain – typically by stealing credit card numbers, social security numbers
and other personal information to aid in identity theft, or anything else of perceived value. It might be industrial espionage – a
competitor or their proxy attempting to obtain client information, strategic planning information, your source code, et cetera.
It could be sabotage - a disgruntled employee or customer attempting to deface your website, corrupt your data, deny service
to legitimate users, or just make your company look bad. Often, the motivation is simply the challenge of breaking in and
perhaps leaving evidence they did so.
DEVASTATING ACCIDENTS
Much attention is given to preventing malicious attacks, especially from the outside, but accidents due to security lapses are
much more common – and typically come from inside the firewall. Ask yourself how many times you have had an intentional
attack reach as far as the database. Then ask yourself how many times you have heard something like one of the following:
“I accidentally dropped the ORDER_ITEM table in PROD. Can you fix it?”
“I thought that I updated MY table, not the real application data.”
“I didn’t know that ‘lsnrctl stop’ could shut down the Oracle listener on another server!”
“Oops! Wrong directory!” (After something like rm –rf *)
“Sure, we can recover it and roll it forward – from last night’s export.”
“I don’t understand… It worked in DEV.”
“I thought my stress test was running against the TEST database. Sorry about bringing PROD to its knees.”
“How did an OEM repository get created in the production application data owner account?”
Any proper implementation of a good security plan will help prevent these kinds of “disasters” as well as malicious attacks.
ASPECTS OF DATABASE SECURITY
There are a number of ways to classify the aspects of data and database security. For our purposes, the following is a succinct
and useful classification:
•
Confidentiality – Data should not be disclosed to anyone not authorized to see it.
•
Integrity – It should not be possible to maliciously or accidentally modify data. The origins of data should be verifiable.
•
Availability – The systems to access the data should be kept working and the data should be recoverable.
It is sometimes debated whether the last of these is really within the realm of security. It is the opinion of this author and most
in the field that availability is indeed a security issue. For example, Oracle Trace and the files
$ORACLE_HOME/otrace/admin/*.dat is exactly this sort of issue. Denial of service (DoS) can be just as crippling if it is
accidental as if it is intentional.
-2-
Paper #537
DBA
SECURITY EVALUATIONS / ASSESSMENTS
PENETRATION TESTS
Penetration tests consist of attempting to detect or exploit potential vulnerabilities in the network, hosts, databases and
applications from the perspective of someone without prior intimate knowledge of the specifics of those systems. They are
typically done by trying well-known exploits, using error messages to determine the most promising avenues of attack, and
adapting the attack to the systems. The perspective is from the outside, looking in.
SECURITY AUDITS
Security audits typically consist of examining the systems in question to determine what security weaknesses could potentially
be exploited. Such activity usually starts with interviews and detailed examination of the systems and applications. This
requires privileged access to the systems and application code in question and access to the administrators and designers of
those systems and applications. The perspective is from the inside, looking out.
It is best to consider both of these as essential. Security audits help identify vulnerabilities that may not yet have commonly
known exploits. They are especially useful for detection of potential avenues of accidental damage or attack. Penetration tests
can sometimes reveal existing vulnerabilities that arise from the way that various layer interact, even if an audit of each layer
independently seems to indicate relatively good security.
SECURITY PLAN
Rather than “policy”, the more inclusive word “plan” is used here. A plan includes the policy and the procedures for the
implementation of that policy. Before one can hope to establish an appropriate data or database security plan, the organization
must establish a global security policy. Unfortunately, many organizations as yet have no such clearly defined policy.
Occasionally one finds a global security policy that is so stringent as to be unenforceable or that simply fails to address reality.
Consider the case where this policy dictates that every password must be changed every thirty days and that no password may ever be placed
in writing. Both are quite reasonable general policy items, but not totally enforceable if there is an application that uses the
“One Big User” model. Which of the hundreds of users of this application should change the password when it expires and
lock all the others out? While the “One Big User” model is inherently bad, such exceptions must be considered – they
sometimes exist in the real world. The most secure system possible is one that is unplugged and inaccessible by anyone, but
that is hardly a practical solution. Any security policy must not just sound good to the authors, but needs to actually be useful.
GLOBAL
A global security plan includes the policy and procedures. It should include such items as:
What happens when someone new starts?
What happens when someone leaves?
What happens when someone is on an extended absence?
Password aging – how long before they expire?
Password complexity – what are the rules?
Login retries – how many are allowed before locking account?
Account unlocking – are accounts locked for some set time or must they be manually unlocked?
Are shared accounts allowed?
How often is the policy or plan reviewed?
-3-
Paper #537
DBA
This is just a small sample of what might be included that may dictate how a local plan for Oracle database systems may evolve.
There are a number of other items that may not play a role in driving your local policy, but may seriously compromise the data
or the database system. Here are a couple:
Are users allowed to save their passwords on client machines?
What happens to discarded or reused disk drives? Are they magnetically wiped or thoroughly destroyed?
LOCAL (DATABASE) SECURITY PLAN
The local security policy is derived from the global security policy or some intermediate-level policy. Rather than elaborate on
the nature of a database security policy or plan here, we will refer the reader to the appropriate section of the Oracle
documentation and other another excellent reference.
Chapter 21 of the Oracle8i Administrator’s Guide
Chapter 23 of the Oracle9i Database Administrator’s Guide
Oracle9i Security Overview
How to Write An Oracle Security Plan – Marlene Theriault (highly recommended!)
www.dbatoolbox.com/wp2001/dbamisc/how_to_write.pdf
DATABASE SECURITY – TYPES OF CONSIDERATIONS
What is required to secure the data and the database depends on what the system does, how the application is designed, and a
host of other factors. For simplicity, we will break this into the following categories:
UNIVERSAL
This consists of considerations that apply to every Oracle database system. This is the focus here, but a few critical topics
from the other areas are also mentioned.
VERSION-SPECIFIC
The version of the Oracle software may determine what is available. For example, the virtual private database first became
available in Oracle8i. Many of the core security-related elements have evolved significantly over time. In some older versions
of Oracle, the number of programs in $ORACLE_HOME/bin/ with the SUID or SGID bits set was over twenty. In most
Oracle 8i and 9i installations it is only oracle and dbsnmp. In some versions of the software the dbsnmp executable is owned by
root, in more recent versions the Oracle software owner owns dbsnmp. Most of the comments here apply only to some of the
more recent versions – 8i and 9i. The constructs for implementing database security have evolved significantly over time also.
In Oracle5, the only grantable privileges were CONNECT, RESOURCE and DBA. In Oracle6, these became roles, but userdefined roles were still unavailable. In Oracle7, user-defined roles became available. With each new version, and often with
each new release, the ability to refine the security of the data and the database has been improved.
OPTION-SPECIFIC
Oracle options may influence the security plan. Oracle Advanced Security may be used to encrypt data sent across the
network (among other things) and the Label Security option may provide more fine-grained data access controls. In addition,
there are sometimes specific precautions that should be taken when using some of the bundled options – advanced replication,
standby databases, etc.
APPLICATION-SPECIFIC
This is the 800-pound gorilla of data and database security topics - often the most difficult with which to deal. Every
application has special security considerations that influence the considerations for data and database security. The application
design and architecture may dictate significant modifications to general “best practice” recommendations.
PLATFORM-SPECIFIC
There are a number of possible security issues that apply only to some specific platform. There are some considerations
specific to Windows, others that are only relevant to Solaris, and yet others that are relevant to any Unix-based system. While
platform distinctions are not in scope here, the examples are Unix-based. In most cases though, the principles are generic.
-4-
Paper #537
DBA
INSTALLATION PREREQUISITES
The first set of topics is what needs to be done to prepare the environment for the Oracle software installation. The
assumption here is that this is to be a fresh installation on a clean server – no previous version of Oracle exists and we
currently have no database on the server. To adapt these suggestions to other scenarios is “left as an exercise for the reader”
as there will be many constraints that dictate modifications.
A SECURE INSTALLATION ENVIRONMENT
•
ENSURE THAT THE SERVER IS ON A SECURE NETWORK SEGMENT OR OFF THE NETWORK
Network security is out of scope here, but there are many sources discussing the topic. One such paper of possible
interest is titled “Making Your Network Safe for Databases” and is available from the SANS Institute “Information
Security Reading Room” at www.sans.org. This specific paper is at www.sans.org/rr/appsec/net_safe.php.
•
ENSURE THAT THE SERVER ITSELF IS ADEQUATELY SECURED
The specifics of this are also out of scope for this paper, but again there are many freely available resources on this
topic. The SANS Institute has a number of papers available in the aforementioned reading room and some very
detailed system-specific checklists available in the S.C.O.R.E. (Security Consensus Operational Readiness Evaluation)
section. Both these areas and several more of interest are easily accessed from the “Knowledge Base/Resources”
menu at www.sans.org. Another area of interest on this page is the link to the Center for Internet Security (CIS). CIS
develops freely available security benchmarks and scoring tools for a number of network devices and operating
systems. By the time of the conference, there should be a set of benchmarks for Oracle available at the CIS site at
www.cisecurity.org. An Oracle security-scoring tool is also being developed by CIS and should be available soon.
•
LOCK OUT NON-ESSENTIAL USERS DURING THE INSTALLATION AND DURING DATABASE CREATION
During the Oracle software installation some commands may be issued that could reveal sensitive information. More
critically, Oracle may create files containing sensitive information in the temporary directory (/tmp in Unix – by
default). In general, one could obtain information, including possibly the SYS password, that they should not have if
they are logged into the host during the software installation or database creation. (There is more on this issue and
suggestions on how to minimize the risks later.)
A COHERENT INSTALLATION PLAN
Prior to even creating the Oracle software owner operating system user account, some serious planning should be done. This
is easier if the enterprise has a clearly defined general security policy and easier yet if one has already developed an Oraclespecific security plan. The following is a partial list of items that require such planning.
•
WHAT OS USERS ARE TO BE CREATED?
The common decision factors include how the principle of least privilege is to be incorporated and whether shared
accounts are to be allowed. Local policy should provide guidelines for these decisions.
• SYSTEM ADMINISTRATOR ACCOUNT(S)
Since this is probably not the responsibility of the DBA it will not be discussed in any detail. Suffice it to say that the
common issues are relevant here also. Should everyone use a shared account (e.g. “root” in Unix)? Or should individual
system administrator accounts be created? Should administrative responsibility for different components of the operating
system and network software be split between different users and groups? The basic principle of “least privilege” is
relevant here as well as in the following sections.
• ORACLE SOFTWARE OWNER
One should have a specific, dedicated OS user that will own the Oracle software. While it is possible to have it owned by
some existing user, like “root” in Unix, this is a serious violation of the principle of least privilege.
The next question is whether this user should be the default “oracle” or something else. The argument against using the
default is that it is too well known. The “security by obscurity” principle dictates using a different username if possible.
While this argument has some merit and is almost a universal recommendation by security professionals, it is the opinion
of this author that it is not really all that critical. For one thing, it is trivial for anyone with access to the server to
-5-
Paper #537
DBA
determine the software owner (ps –ef | grep smon, ls –ld $ORACLE_HOME, etc.). The common response to this
argument is that if one does not have access to the server, knowing a valid username is half of the battle to gain access.
This should certainly not be true. It is essential to require a strong password for all host accounts, especially privileged host
accounts. Brute-force attempts to gain access to the host should be trapped by host-level security. Also, by this same line
of reasoning, one should never have a “root” user on Unix, or an “Administrator” account on Windows.
On the other hand, there is nothing particularly sacred about naming the account “oracle”. If you have the opportunity, it
is better to use something else. However, be aware that some third-party software may not install or function correctly if
the username is not the default
Another common suggestion by security professionals is that different OS-level users should own various components of
the software. In general, one could install the basic RDBMS software as one user, the Oracle networking components as
another, the intelligent agent as yet another, and possibly other components as being owned by different users yet. Many
sources recommend this and say that this is particularly recommended for the listener. With one significant exception (the
extproc listener – discussed later), this is not considered particularly critical by this author. While it may result in a
somewhat more secure system, the cost in operational complexity is usually not justified. If the administration
responsibilities of various components are segregated into distinct groups, this is probably required. If the system is
already in operation, this may not even be feasible. In addition, there are usually simpler ways to adequately secure
potentially troublesome components. However, this independence may make it easier to do things like update the
intelligent agent or networking software without updating the core database software.
In all cases, using the software owner account for routine activity should be discouraged. After the software is installed
and the system configured, this account should be locked and unlocked only for software upgrades, patches and other
such activity. If this is not feasible in some current environment, at least this account should have a strong password.
• DBA ACCOUNT(S)
One should determine, based on local policy, exactly who the administrator(s) of the database and the Oracle software will
be. It is generally considered bad practice to log in as the software owner to perform routine DBA functions. It also
becomes difficult to perform useful auditing if everyone shares an account. It is highly recommended to create individual
accounts for database administrators and use the software owner account only for those activities that truly require it –
software installation, upgrades, and patches for example.
• OPERATOR ACCOUNT(S)
Does the organization need one or more accounts specifically created for database operators? Are these functions actually
performed by the DBA? If so, should one create operator accounts anyway – so that operator-specific functions (e.g.
backups) are performed under a less privileged account, even if the DBA actually performs all these tasks? Should a single
shared, generic operator account be created or should each operator have a unique OS account? General security
guidelines always recommend against shared accounts and against performing almost any activity from an account with
privilege beyond the minimum required. The trade-off is again between operational complexity and security.
• AUDITOR ACCOUNT(S)
Perhaps the organization has dedicated auditors. Perhaps there is even a distinction between system auditors, database
auditors, and/or data auditors. In most organizations, the DBA also serves as the database auditor and the system
administrator also serves as the system auditor. If there is a distinction between administrators and auditors, then it is
important to create accounts for auditors that have some specific privileges that even administrators do not have. In
particular, the audit trail should be accessible and modifiable only by the auditors. Since the Oracle software owner must
be able to write to the audit trail, the auditor must be able to control access to that account. The same considerations
about shared accounts are in play for auditors.
• APPLICATION ADMINISTRATOR ACCOUNT(S)
If the server is not a true dedicated database server, it may be necessary to create one or more application administrator
accounts. Although this is becoming less common, it is still sometimes required. All the considerations for other types of
administrative accounts are applicable here also. This decision and the account administration may or may not be the
responsibility of the DBA, depending on the nature of the application, the nature of the DBA role in the organization and
local policy.
-6-
Paper #537
DBA
• APPLICATION USER ACCOUNT(S)
It is fairly rare these days to see systems where application users require host-level access to the database server. This
model is not completely extinct though. In many of those cases, the real users share one common account - the One Big
User model. This also is subject to all the aforementioned considerations, plus a few others. This also may or may not be
the responsibility of the DBA.
•
WHAT OS GROUPS ARE TO BE CREATED?
To focus this a bit more, only OS groups directly related to database security are discussed. Obviously, other types of
users mentioned above may benefit from OS groups also.
• ORA_INSTALL
The first consideration is whether a distinct group, typically “oinstall”, is preferred or whether the OSDBA group alone is
sufficient. The first question is whether the same group is responsible for software maintenance and database
administration. The second is whether all databases on the server are administered by the same DBA(s). If the answer to
either of these is “No”, then the ORA_INSTALL group is required. Rather than discuss this in any detail here, please
refer to MetaLink note 114740.1.
Even if not required, it is recommended in most situations to use a group other than the OSDBA group for the software
installation. Use of a distinct software owner group setting permissions on some files and directories for only access by
this group and the software owner can help prevent accidental damage by others – including members of the OSDBA
group. If there is any possibility of later creating either of the situations described in the last paragraph, then the install
group is required. It is better to use it from the beginning than to have to change it later.
• OSDBA
As discussed in the aforementioned MetaLink note, if there are multiple databases on the server, they are administered by
different groups of DBAs, and these DBAs should not have any privilege in databases other than the ones they administer,
then a different OSDBA group for each database is required.
In most situations, the main considerations here are what group name to use and who should be members of the group.
In Unix, “dba” is the default and so common as to be almost universal. However, there is nothing sacred about the name.
One should practice “security by obscurity” by using a less well-known group name. There may be some third-party
software constraints on this that prevent using a non-default name though.
If one changes the OSDBA group (or the OSOPER group) after the software is installed, one needs to modify the file
config.c (or possibly config.s) in $ORACLE_HOME/rdbms/lib/ and relink the oracle executable.
• OSOPER
Should there be an OS group for operators? It depends on the division of responsibilities in your organization. If DBAs
perform all the operator functions that require host-level access to the database server, then perhaps you don’t need such a
group. The “principle of least privilege” may lead one to create an OSOPER group and distinct users anyway and use
those accounts to perform operator functions, rather than use the more privileged OSDBA group. This could prevent
DBAs from invoking the grater privileges of the dba role while performing operator functions. The decision is yours and
works in conjunction with the choice about operator accounts in the previous section. The answer to this question also
should be dictated by local policy.
• OTHER?
In addition to these, one may want to create other database-oriented groups – for application administrators, developers,
etc. The creation and administration of these accounts may or may not be the responsibility of the DBA. It is more likely
that they are the responsibility of the system administrator or the security administrator. However, the DBA needs to be
at least aware of what is planned in this area. Too often, such accounts are over-privileged. For example, there is no good
reason that any developer should ever belong to the OSDBA or “root” group, even on a development server.
•
WHAT DATABASE USERS ARE TO BE CREATED?
Much of this depends on what options are to be installed, what type of system it is (development, production, …) and, of
course, the application. With each new release of Oracle, there are more accounts created by default. It is important to, in
-7-
Paper #537
DBA
the planing stage, determine which are useful and which are simply clutter – and to plan the installation so as to minimize
the post-creation cleanup. In 8i, the minimal set includes SYS, SYSTEM, and OUTLN. 9i adds WKSYS. We will deal
with the accounts that Oracle may create in more detail later.
•
WHAT DATABASE “GROUPS” (ROLES) ARE TO BE CREATED (OR DISABLED)?
There are typically a number of roles created during the database creation also – whether using dbca or creating the
database manually. Going all the way back to Oracle6, CONNECT, RESOURCE, and DBA are always created. With
each new version, several more default roles have been added. The default installation creates some rather privileged roles
that are likely to be unnecessary. The application should use roles to ease privilege management and will typically require a
specific set of roles to be created. This also is dealt with in more detail later.
•
HOW WILL THE SYSTEM BE LAID OUT?
• DISKS
Without turning this into a dissertation on tuning, there are some considerations here that certainly lie in that gray area of
security – availability. Thus it is important that the DBA intimately involved in, or at least knowledgeable of, the physical
layout of the server. For example, it is not a particularly good idea to have the archive log destination on the same disk(s)
or controller as the database datafiles – even if everything is mirrored and distinct filesystems are created for datafiles and
archive logs. This is a rather obvious point to be sure, but it is surprising how many times DBAs are handed servers
whose layout violates not only OFA, but also perhaps even common sense. If the database becomes unusable or
unrecoverable because of some such flaw in the layout, it will likely be the responsibility of the DBA to “fix it” later.
• FILESYSTEMS & DIRECTORIES
OFA. Need we say more? Well, perhaps… OFA is often seriously misunderstood. For example, the filesytems do not
have to be named “/u01”, “/u02”, etc. This is an example in OFA, not a literal commandment. OFA is a set of guidelines,
not a set of stringent absolutes carried down from the mountain by Cary Millsap on stone tablets. What is important is to
follow the guidelines and the spirit of OFA, not to dogmatically follow all the examples verbatim.
From a security perspective, it is important that all filesystems and raw devices critical to the database, the Oracle software,
the software owner, and all privileged OS users be protected. There may be an ORA_INSTALL group that is distinct
from the OSDBA group, or they may be the same: ORA_INSTALL = OSDBA. Likewise, there may be distinct
OSOPER and OSDBA groups – or the OSDBA group may also perform the operator function. Due to these and many
other local variables, it is difficult to state with definitive authority exactly what permissions should exist on many of the
database files and software components. Many security sources say that all of ORACLE_HOME should be even readable
only by the software owner – and perhaps the ORA_INSTALL and/or OSDBA groups. This doesn’t work if there are
host accounts on the server that need to be able to run SQL*Plus and other such programs. For example, even if the
necessary executables are world executable they will error out when they cannot access the message files. In the following
discussion, it is more important to identify sensitive files and directories that should definitely have restricted permissions
than to try to dictate the exact privileges that every file and directory should have. In Unix cases where it may be desirable
to have some permission for multiple groups, but not for world, file access control lists are in order. Some version of
setfacl is available for most Unix-like systems.
oraInventory – (defined as inventory_loc in /etc/oraInst.loc, or /var/opt/oracle/oraInst.loc or some other place)
should be writable and readable only by the ORA_INSTALL group and the software owner. The directory is typically
$ORACLE_BASE/oraInventory in Unix.
$ORACLE_HOME – Everything under this directory should be owned by the software owner and the
ORA_INSTALL group. All files and all subdirectories should have write permissions only for the software owner
and the ORA_INSTALL group unless specified otherwise. There are some legitimate variations based on local policy.
The OSDBA group may need read/write on some files.
$ORACLE_BASE – All files and subdirectories should be owned by the software owner and the OSDBA group or
the ORA_INSTALL group. No other permissions should be necessary except for files and directories in
ORACLE_HOME.
-8-
Paper #537
DBA
$HOME – The home directories of the software owner, in particular, and any members of the OSDBA or
ORA_INSTALL group should be writable only by the owner, but perhaps readable by the ORA_INSTALL or
OSDBA group. Nothing should not be readable by the world at large.
Directories containing database files – This includes any datafiles, redo logs, control files, and whatever else (e.g.
bfiles?) may constitute the database. These should be writable only by the software owner and readable only by the
ORA_INSTALL group. Even the read privilege on datafiles may compromise the confidentiality of the data. If
manual backups are run where members of OSOPER or OSDBA need read permission, this may be accommodated.
Raw devices for database files – Raws require some special considerations. It is usually possible, depending on the
system and volume management software, to segregate raw devices reserved for the database into distinct disk groups
and/or volume groups. This should be done and the groups should be clearly identified by name as belonging solely
to the appropriate user and group. It is much easier than trying to recover a database after an unaware system
administrator has built a filesystem, for some extraneous purpose, on top of the raw device for one of your datafiles!
Another consideration is that the actual physical location of raw devices is often not obvious. You don’t want
someone to create a “foreign” filesystem on the same physical disk as one of your performance-critical database
components. We can (barely) justify this in a security discussion by saying that it falls under “availability”.
Archive log destination(s) – should be writable and readable only by the software owner, the ORA_INSTALL or
OSDBA group or perhaps the OSOPER group. If someone can read your archive logs, they can read changes to your
data – including perhaps things like “alter user SYS identified by …”. It may not be trivial, but it is possible. (If they
have access to logminer, it is almost trivial!) World should not have read permission on anything here.
Backup and export directories – If one performs any sort of backup to disk, these directories must be protected also.
If one performs database exports, those too can be used to retrieve sensitive information – your data, passwords
(hashed, to be certain, but crackable), etc. Permissions should usually be the same as the archive log destination(s).
•
WHAT OPTIONS WILL BE INSTALLED?
• INSTALL ONLY WHAT YOU NEED – OR WILL SOON NEED
For the software installation, plan to install only the software options that will actually be used or might be needed soon.
If too much is installed, there is more cleanup work to be done afterward.
In planning for the database creation, choose only those options actually needed. Most database options may be added
later without downtime. Some require an instance restart though and may be initially installed, disabled, then enabled if
needed. Some of the available options require special security considerations. For example, the interMedia option (or
Context, or Oracle Text – depending on the version) creates a user CTXSYS with DBA privilege. It is possible to tighten
up on some of the default privileges or lock the account, but if you don’t actually use it why have the exposure at all.
There are several other notable examples – a few will be mentioned later and some are “out of scope” here.
•
WHAT UPGRADES OR PATCHES WILL BE INSTALLED?
Prior to creating the database, it is advisable to install any desired patch sets (e.g. 9.2.0.2) and to identify and install other
appropriate patches. Today many of these one-off patches are designed to rectify security-related problems.
SOFTWARE INSTALLATION
Since the pre-installation planning has us so well prepared, this should be easy! There are a few additional considerations that
might be deferred until this phase though.
TEMPORARY DISK SPACE
A directory is used by Oracle during the installation for temporary disk space. There is some risk in using the default
temporary directory during the installation. In Unix, this default is /tmp/. Oracle creates files and directories in this directory
during the software installation that may contain sensitive information – orainstRoot.sh, perhaps a response file, an OraInstall
subdirectory, and/or others. If a malicious user can predict what the names of these files or directories will be and pre-create
them, Oracle will overwrite them, but the original permissions may be kept. This user could then harvest sensitive information
-9-
Paper #537
DBA
from the files. The way to prevent any possibility of this is to set the appropriate environmental variables to some protected
directory – where only the software owner and ORA_INSTALL group have any permission.
The maximum temporary space required varies with version and perhaps platform. The 8i Unix documentation says “up to 75
MB” and the 9iR2 Unix documentation says “up to 400 MB”. Check the platform-specific installation guide to be sure.
There are typically two environmental variables that control the location – one for the Oracle installer (e.g. $TMP) and one for
the operating system (e.g. $TMPDIR). . The first is used by Oracle and may be version-specific. The latter is used during the
linking of program executables and is OS-specific. Both should be set to the same protected location during the software
installation. The specifics may be found in the platform-specific installation guide and the platform-specific administrator’s
reference – usually in the “Environmental Variables” section. There are often inconsistencies in the variable names between
the two documents. For example, in all the 9iR2 Unix documentation sets that were checked by the author, the installation
guide said the variable names were TMP and TMPDIR, but the administrator’s reference said TEMP and TMPDIR. The
second variable name also varies between Oracle versions of the documentation – in 8i, it is stated to be TMP_DIR on most
Unix platforms. The author has seen these variables referred to as TMP, TEMP, TMPDIR, TMP_DIR, TEMPDIR, and
TEMP_DIR in various Oracle documents, Metalink notes, and third-party papers. It is important to check all the relevant
documentation for the particular version and platform. If in doubt, set them all! After the installation, one may wish to let
them return to the system defaults.
CREATE A DATABASE DURING INSTALLATION?
Should one let dbca create the database during the install – or defer it until later? The recommendation is to defer database
creation until after the software is installed, upgraded, and patched. Many patch sets and a few one-off patches require a
database migration, running a new catalog.sql, catproc.sql or some actions that may make the entire process take much longer
if the database already exists. Another consideration is that if one creates a database during the installation process, the
database may be vulnerable until security patches are applied. One can run dbca after the software is installed and patched.
CONFIGURE ORACLE NETWORKING DURING INSTALLATION?
Should one configure the listener and other networking components during the installation process – or defer it until later?
For the same kind of reasons, it is advisable to defer listener configuration until after all software upgrades and patches are
applied. This is especially true here since once the listener is running, the system is accessible – even if the database is not.
This is important for several reasons, not the least of which is that the default configuration includes an extproc service. A
further incentive is that the listener is likely to require one or more significant security patch and some custom configuration.
DATABASE CREATION
We are fairly well prepared here as well, but again there are a number of considerations that may be deferred until now.
MANUAL DATABASE CREATION – OR DBCA?
If using dbca, be aware that accepting all the defaults is usually wildly inappropriate. Many unnecessary default accounts and
objects are created and unnecessary database options are likely to be installed. In 9i, there many be 40+ such accounts! At
least in 9i, dbca prompts for a SYS password, prompts for a SYSTEM password and locks and expires most of the default
accounts. In most previous releases, dbca creates all these users with default passwords and leaves the accounts open.
(Another good reason to lock out non-essential users during the process.) In some Oracle8i releases a few of the default
accounts are given an unusable password and must be given a new one before they can be used. Also be aware that dbca may
create scripts that may contain passwords – in clear text – and that the scripts may be left on disk long after the database
creation is complete.
If creating the database manually (from custom scripts or scripts saved from dbca) one should also protect the scripts and any
log files they may create. If using scripts generated by dbca, one has the opportunity to edit them to remove unnecessary
components and make other customizations before running them to create the database.
The recommendation here is to either create the database manually or to extensively modify the defaults in dbca.
DIRECTORIES FOR THE DATABASE – DATAFILES, CONTROL FILES, LOG FILES, ETC.
Since this has been planned earlier, all we may need to do now is verify that what we planned is actually what we have.
- 10 -
Paper #537
DBA
INITIALIZATION PARAMETERS
To create a database, we have to start an instance. To start an instance we need an initialization file, so perhaps this is the time
to talk about some security-related initialization parameters. We might as well set most of these now so we don’t forget to
modify them later.
For simplicity, we will assume from here on that the instance name is the same as the database name: SID=DBNAME. There
are scenarios where this is not the case – OPS or RAC in particular. Also, there is some “security by obscurity” advantage to
using something other than the database name as the instance name. However, the author’s opinion is that the better security
recommendation is to, if possible, use a listener service name different from the actual database name or instance name and to
dynamically register the instance with the listener. In any case, the service name, database name or instance name should never
be the default (usually ORCL).
For the sake of brevity, we will adopt the abbreviation SID for $ORACLE_SID and DBNAME for the database name.
If using Oracle9i the first consideration is what type of initialization file to use – a pfile or an spfile. The default location for
either file is in $ORACLE_HOME/dbs/. The default name of the pfile is initSID.ora and for the spfile it is spfileSID.ora. If
using the spfile, the pfile may contain just one line: “spfile=<location and name of the spfile>”. For example:
“spfile=spfileORCL.ora”. (Note that the full path is not required if the file is in the default location.) OFA says we should
create the real pfile in $ORACLE_BASE/admin/SID/pfile/ directory and create a soft link to
$ORACLE_HOME/dbs/initSID.ora. The real security issue here is that whatever pfile, spfile, and/or ifile we may use
should be protected. There is no reason that world should have even read permission on either the file or the directory. There
are a number of advantages to a malicious user in knowing some of the information contained in these files. Some of the
reasons will become apparent shortly. If an unauthorized user can modify a pfile, spfile, or ifile they can seriously compromise
the integrity of the system.
For the following discussion, let us use “..” to mean “some appropriate value” and the conventional “?” to indicate
$ORACLE_HOME. Also, parameters and values are in italics while comments are preceded with a # or are in normal text..
First, some directory and file parameters are considered. All these files and directories should have read & write permissions
ONLY for the software owner and the appropriate group (OSDBA or the ORA_INSTALL group in some scenarios).
ifile = ..
Many Oracle security recommendations say “do not use an ifile”, but the important thing is its protection.
utl_file_dir = ..
This should not be “*”, “.”, user_dump_dest, or any other directory where anything of value or any sensitive information may
be stored. Any user or process can write here with the permissions of the software owner. There is no distinction between
applications, processes, users, etc. Leave it out altogether if it is not needed.
control_files = ..
Three control files on different disks and at least two distinct controllers are recommended. The control files and their
directories should have no world permissions.
log_archive_dest = ..
log_archive_duplex_dest = ..
# or
log_archive_dest_1 = ..
log_archive_dest_2 = ..
log_archive_dest_n = ..
# For Oracle8i, n in (1,2,3,4,5).
For 9i, n in (1,2,3,4,5,6,7,8,9,10)
All possible archive log directories must be protected – even if on remote machines!
log_archive_start = TRUE
We generally want to turn off archive logging for database creation, but (almost always) turn it on later. The exceptions are
those rare cases where we do not need to have full recoverability. When we do start archiving, we don’t want to forget to turn
- 11 -
Paper #537
DBA
automatic archiving on. It won’t hurt to set this to TRUE even for database creation – the arch process will run, but archive
log files will not be generated until we “alter database archivelogmode” sometime after database creation (typically).
_trace_files_public = FALSE
user_dump_dest = $ORACLE_BASE/admin/SID/udump
background_dump_dest = $ORACLE_BASE/admin/SID/bdump
core_dump_dest = $ORACLE_BASE/admin/SID/cdump
Trace files quite often contain sensitive information. “$ORACLE_BASE” is not really valid syntax here, it is a convenient
abbreviation for our purposes.
audit_dump_dest = $ORACLE_BASE/admin/$DBNAME/adump/
The default is $ORACLE_HOME/rdbms/audit/. The location and permissions will depend on whether the DBA is the
auditor or there is a distinct auditor and whether there are multiple databases with distinct groups of DBAs n the server.
audit_trail = OS | DB
Possible values are OS, DB, TRUE, FALSE, and NONE – depending on version. The default is NONE. OS=OS files,
TRUE=DB=in SYS.AUD$, NONE=FALSE=disabled. The key question is “Should the audit trail be stored in the database
or in system files?” This will be discussed in detail later in the auditing section.
o7_dictionary_accessibility = FALSE
The default in 9i is FALSE, in previous versions it is TRUE If TRUE, it allows anyone with the “select ANY table” system
privilege to read the data dictionary, including such items as SYS.LINK$, SYS.USER$, etc. Test this thoroughly! It can break
some applications – especially some 3rd part apps.
max_enabled_roles = 30
This should be as limited as possible. SYS may need 20 by default so 30 seems to be a reasonable value.
processes = <something reasonable>
Accidental or intentional DoS is possible if too high (or too low!)
os_authent_prefix = ‘’
The recommended value is a null string – two consecutive single quote marks. The default is OPS$. If OPS$ is used, any user
with an OS username of “someuser” may use OS authentication for a database account named “OPS$SOMEUSER” even if
this account is created with a password. By setting this to a null string, only users explicitly created via “create SOMEUSER
identified externally” may use OS authentication and externally identified accounts cannot be used remotely by supplying a
password.
os_roles = FALSE
If this is TRUE, roles are defined at the OS level.
remote_os_authentication = FALSE
If true this allows the client to authenticate the user. Setting this to true introduces a major security hole.
remote_os_roles
= FALSE
We don’t want to allow os_roles – and we certainly don’t want to allow remote_os_roles!
remote_login_passwordfile = NONE | EXCLUSIVE
The default is NONE and means that no privileged connections are allowed over non-secure connections. EXCLUSIVE
means that a password file may be used with only one database and it allows users other than SYSOPER and SYSDBA to be
included. If remote administration as sysdba or sysoper is not required, set this to NONE. If remote connections as sysdba or
sysoper are required, set this to EXCLUSIVE. Typically, this should be NONE for most Unix servers and EXCLUSIVE for
most Windows servers.
- 12 -
Paper #537
DBA
global_names = TRUE
If TRUE, a database link is required to have the same name as the database to which it connects. This can be difficult in a
large, complex environment though. If more than one public database link is needed to any single remote database, this
cannot be TRUE. The recommendation is TRUE to enforce global naming. TRUE is required for advanced replication.
dblink_encrypt_login = TRUE
If FALSE, the default, then a database link login will encrypt the password for the first try, then retry with a clear text
password. If this parameter is set to TRUE, the first attempt is encrypted. If it the first attempt fails, there is no retry – the
connection fails. This is a depreciated parameter in 9i. As of 9iR2, at least, all retires are encrypted regardless of this setting.
See later discussion about listener configuration and networking.
osauth_prefix_domain = TRUE
This is windows-specific. If externally identified accounts are required, this forces the account to specify the domain and helps
prevent spoofing from another domain
# dispatcher = (PROTOCOL=TCP)(SERVICE=orat92XDB)
If this entry is generated for you in 9iR2, comment it out. If left in, it enables default configuration of ports ftp:2100 and
http:8080. If not removed, unsuccessful login attempts are not logged. Alternately, the log level could be changed in
Enterprise Manager (This is all hearsay – this parameter is untested by the author.)
remote_listener
= <some service name for remote listeners with which to register>
Remote listeners are often used for load balancing in a RAC environment. Do NOT set this parameter unless you are fully
aware of what it does!
service_names = gl.anyorg.com, ar.anyorg.com
# or
service_names = GL, AR
These are the service names with which the instance will dynamically register with the listener.
Note:
Not all of these parameters are applicable or even available in all versions of Oracle. Individual platforms may also
limit or expand the set of initialization parameters that impact system security. Please check the appropriate platform
and version specific documentation.
POST-INSTALLATION / POST-CREATION OF DATABASE
There are some files usually created during the software installation and/or database creation that we need to delete. There are
also files and directories that may need to have their default permissions changed. Some of these tasks are dependent on the
version, the installation method, and the database creation method.
If there is a distinction between the OSDBA group and the ORA_INSTALL group, we may wish to modify the directories to
have read and write permission only by the software owner and the ORA_INSTALL group.
FILES & DIRECTORIES
$ORACLE_HOME - Unless specified otherwise, or there is some very compelling reason to do otherwise, everything
under this directory should have write permission only by the software owner and ORA_INSTALL group (e.g. oinstall,
dba, …). If used, the OSOPER group may have read permission – to perform backups and other tasks. . Depending
on local policy, the OSDBA group may need read and write permissions on large parts of it also.
$ORACLE_HOME/bin/ - Check default permissions on all files.
rm *.O *.0
- 13 -
Paper #537
DBA
Check for files with SUID bit set. If possible, remove all SUID and SGID settings.
oracle
dbsnmp (depending on version)
others (depending on version)
Executables to perhaps remove or change to non-executable. All should be executable only by the software
owner and the OSDBA group in any production environment - if at all possible.
tkprof
extproc (remove if possible! At least chmod o-rwx extproc)
lsnrctl (default permission is world executable! chmod o-xrw lsnrctl )
sqlplus (Many security sources say this executable must be deleted! If possible, chmod o-rx sqlplus)
svrmgrl (Those same sources say this must be deleted also. If both are deleted, how does one stop or
start an instance? These kinds of suggestions fall into the category of “myths and folklore”)
$ORACLE_HOME/otrace/admin/ - rm *.dat
$ORACLE_HOME/network/admin/
sqlnet.ora and tnsnames.ora – world read only if necessary
listener.ora – group read/write, no world permissions at all. chmod o-rwx listener.ora
dbsnmp_rw.ora – remove world read permission ! chmod o-rwx dbsnmp_rw.ora (snmp.ora in some versions)
$ORACLE_HOME/dbs – orapwSID, initSID.ora, spfileSID.ora – no world permissions – not even read.
$TMPDIR – delete all files and directories owned by oracle created during software install
For Oracle’s official statement on file permissions, see the appropriate documentation. For Oracle 9iR2 on most Unix
platforms it is:
HTTP://DOWNLOAD-EAST.ORACLE.COM/DOCS/HTML/A96167_01/POST-INST.HTM#G1055563
These are not really very secure permissions, but it might be informative to know what the they say.
DEFAULT DATABASE USER ACCOUNTS
If using dbca to create the database, SYS, SYSTEM, and perhaps some other default account passwords may be customized
during database creation. In 9i dbca, a default temporary tablespace is defined at database creation time and most of the
default accounts are locked and the password expired.
DEFAULT USERS
Drop all users that are not actually needed. These may include SCOTT, CTXSYS, DBSNMP, and many others.
If dropping the user is not possible, lock the account and expire the password if possible. WKSYS, OUTLN, and some others
are candidates for this. (Note: Do NOT drop OUTLN or WKSYS (9i)! These objects these own are used by Oracle even if
no other reference or access is ever made. These two may be locked, but not dropped. Other accounts may fall into this
category also. The primary criteria are that the account owns objects that are needed, but nobody needs to log as the user.
Change the default passwords on any remaining accounts. These include SYS, SYSTEM, and perhaps others. For some
password changes, it may be advisable to modify the account creation scripts to include the changed password (DBSNMP and
- 14 -
Paper #537
DBA
the catsnmp.sql script is a prime example). If this is done, make sure that the permissions on the script are such that
unauthorized users may not read them to obtain the password.
Here are some specifics for some of the more privileged default users in 8i and 9i. It includes the username, a short
description and the name of the 8.1.7 script to drop the user and perhaps some roles and objects. Be aware that the names and
location of these scripts is subject to change – many changed between releases of 8i or between 8i and 9i. Many others or
variations on these locations and names may be found by searching $ORACLE_HOME/*/*/*.sql with a utility like Unix grep.
DBSNMP
CTXSYS
MDSYS
ORDSYS
PERFSTAT
Only used by the intelligent agent.
InterMedia (ConText, OracleText)
Spatial Option
Time Series Option
Stats Pack
$ORACLE_HOME/network/admin/catnsnmp.sql
$ORACLE_HOME/ctx/admin/dr0dsys.sql
<none?>
<none?>
$ORACLE_HOME/rdbms/admin/spdrop.sql
Be particularly aware of the privileges granted to PERFSTAT, CTXSYS, DBSNMP, MDSYS and some of the other default
accounts. CTXSYS is granted the DBA role. MDSYS and PERFSTAT do not have the DBA role, but do have a lot of
sensitive privileges. DBSNMP has the CONNECT and RESOURCE roles and powerful privileges like SELECT ANY
DICTIONARY.
ACCOUNT ATTRIBUTES
Default tablespace – no user except SYS should have SYSTEM as their default tablespace.
Temporary tablespace – no user, including SYS, should have SYSTEM as their temporary tablespace.
(In 9i, use “alter database default temporary tablespace TEMP” – before creating additional users.)
Profiles – (We will deal with profiles in detail later).
Tablespace quotas – Assign as appropriate. Nobody except SYS should have any quota on SYSTEM tablespace.
ORACLE DATABASE PASSWORDS
Passwords for database users demand some special consideration. Often, general security policy defines the standards for
strong passwords. Perhaps this is something like “All passwords must be ten characters or longer, containing at least three of
the following types of characters – upper case, lower case, numbers, special characters.” Since Oracle passwords are not case
sensitive and the only officially supported special character is an underscore (“_”), the possibilities are a bit limited. One can
use double quotes around passwords to use some non-supported characters, but who knows what some application interfaces
may do with those double quote marks. Be very careful of special characters. For example, “@” is a particularly poor choice.
In most cases, anything after the @ will be assumed to be a net service name. Also beware of anything that might be
interpreted in the environment (e.g. $ in Unix, # in Unix, etc.).
See the Schema Object Names and Qualifiers section of the Oracle SQL Reference Manual for a full discussion of what restrictions
exist on passwords. A few excerpts from this section in the Oracle 8.1.7 documentation follow. (Note: Some constraints are
omitted because of their irrelevance to passwords.)
Passwords must follow the rules described in the section “Schema Object Naming Rules”, unless you are using Oracle's
password complexity verification routine. That routine requires a more complex combination of characters than the normal
naming rules permit. You implement this routine with the UTLPWDMG.SQL script, which is further described in the Oracle8i
Administrator’s Guide.
The following rules apply when naming schema objects:
1.
Names must be from 1 to 30 bytes long
- 15 -
Paper #537
DBA
2.
Names cannot contain quotation marks.
3.
Names are not case sensitive.
4.
A name must begin with an alphabetic character from your database character set unless surrounded by double quotation
marks.
5.
Names can contain only alphanumeric characters from your database character set and the underscore (_), dollar sign ($),
and pound sign (#). Oracle strongly discourages you from using $ and #.
6.
A name cannot be an Oracle reserved word. (Author’s note: This does not apply to passwords.)
12. A name can be enclosed in double quotation marks. Such names can contain any combination of characters, including spaces,
ignoring rules 3 through 7 in this list. This exception is allowed for portability, but Oracle recommends that you do not break
rules 3 through 7.
If you give a schema object a name enclosed in double quotation marks, you must use double quotation marks whenever you
refer to the object.
Enclosing a name in double quotes allows it to:
o
Contain spaces
o
Be case sensitive
o
Begin with a character other than an alphabetic character, such as a numeric character
o
Contain characters other than alphanumeric characters and _, $, and #
o
Be a reserved word
If you give a user or password a quoted name, the name cannot contain lowercase letters.
Although column aliases, table aliases, usernames, and passwords are not objects or parts of objects, they
must also follow these naming rules with these exceptions:
•
Do not use quotation marks to make usernames and passwords case sensitive.
PROFILES
As defined in the data dictionary (in the RESOURCE column of the SYS.DBA_PROFILES view), there are two basic types of
profile components: kernel limits and password controls. Kernel limits could be broken down further into resource utilization
limits and connection limits. For the purpose of this discussion we will use the latter three categories. It is recommended to
modify the default profile if possible. If this is not possible, the default profile should be used only for accounts where it is
absolutely required. The DBA should create an appropriate set of profiles and assign them to users. The number or profiles
needed and the limits for each is dependent on the application, the types of users, and local policy.
For example, consider a situation where real users (Mark, Sally, …) may connect via client-server, the web site connects via
some middle tier that uses a shared account to connect to the database and there are several power users to run reports,
perform application-specific batch jobs, etc. One might create three profiles for these three classes of users. POWER_USER
might have high (or no) resource utilization limits, standard password controls, and high connection limits. REAL_USER
might have fairly low resource utilization limits, standard connection limits, and standard password controls.
SHARED_USER might have few, if any, resource limits or connection limits and relaxed password controls.
Reasons one might want to relax or modify the standard password controls for SHARED_USER might be:
If there are 400 “real users” connecting as APP1, which of them should change the password when it expires – and
lock the other 399 out?
- 16 -
Paper #537
DBA
If the APP1 password is provided by the application (e.g. the user logs in with an application username and password,
the application authenticates the user, and then connects to the database as APP1 on the real user’s behalf) then
perhaps a single password failure is cause for concern. In this case, should the account be locked? Perhaps a trigger
should catch this failure and the administrator immediately alerted.
If some middleware uses persistent connections as SHARED_USER, then the user should probably not be limited as
to idle time, connect time, and some other parameters.
Category
Resource_Name
Description
Connection
IDLE_TIME
In minutes
(kernel)
CONNECT_TIME
Minutes – cumulative for session
SESSIONS_PER_USER
Maximum number of concurrent sessions for user
Resource
CPU_PER_CALL
CPU time limit per call – parse, execute, fetch (1/100 seconds)
(kernel)
LOGICAL_READS_PER_CALL
As it sounds
CPU_PER_SESSION
CPU time limit per session (1/100 seconds)
LOGICAL_READS_PER_SESSION
As it sounds
COMPOSITE_LIMIT
Rather complicated – see documentation
PRIVATE_SGA
Rather complicated – see documentation
Password
FAILED_LOGIN_ATTEMPTS
Consecutive failed login attempts before account is locked
(password)
PASSWORD_GRACE_TIME
Days grace after first login attempt after expiration before account expires
PASSWORD_LIFE_TIME
How many days after change before password must be changed again
PASSWORD_LOCK_TIME
Days to lock account. (UNLIMITED = Must be unlocked by DBA)
PASSWORD_REUSE_MAX
Number of password changes before password can be reused
PASSWORD_REUSE_TIME
Number of days before password can be reused
PASSWORD_VERIFY_FUNCTION
Name of password complexity verification function (owned by SYS)
If either PASSWORD_REUSE_TIME or PASSWORD_REUSE_MAX is set, the other must be unlimited!
Sample script to create a profile:
create profile REALUSER limit
--- Session limits
--- If a session is idle for over 2 hours it gets terminated.
IDLE_TIME 120
-- To prohibit “eternal sessions”, allow connection time of only 12 hours.
CONNECT_TIME 720
SESSIONS_PER_USER 1
--- Resource Utilization Limits
--- If any single call takes > 30 seconds or incurs more than 100,000 logical reads,
-- we want them to call and complain! Otherwise, resource utilization is unlimited.
CPU_PER_CALL 3000
LOGICAL_READS_PER_CALL 100000
CPU_PER_SESSION unlimited
LOGICAL_READS_PER_SESSION unlimited
COMPOSITE_LIMIT unlimited
PRIVATE_SGA unlimited
--- Password controls
- 17 -
Paper #537
DBA
-FAILED_LOGIN_ATTEMPTS 5
-- If account becomes locked, an administrator must explicitly unlock it
PASSWORD_LOCK_TIME UNLIMITED
PASSWORD_LIFE_TIME 30
PASSWORD_GRACE_TIME 7
-- Passwords may never be reused
PASSWORD_REUSE_MAX UNLIMITED
PASSWORD_REUSE_TIME UNLIMITED
PASSWORD_VERIFY_FUNCTION pwd_verify_function
/
alter user DGRANAMAN profile REALUSER;
These values are not recommendations! This is just a sample script showing what is available.
The function specified as the PASSWORD_VERIFY_FUNCTION must be owned by SYS. A sample script is supplied in
$ORACLE_HOME/rdbms/admin/utlpwdmg.sql to create a function named VERIFY_FUNCTION. Be aware the this
script alters the DEFAULT profile. If this is not desired or VERIFY_FUNCTION is to be modified, then copy the script
somewhere else and edit the copy as desired. One could rename the default VERIFY_FUNCTION if it is modified least
someone run the original utlpwdmg.sql and redefine the function. In the script above, the modified function is named
PWD_VERIFY_FUNCTION.
The syntax for disabling the password_verify_function after setting it is not obvious. A query on SYS.DBA_PROFILES will
show a value of ‘UNLIMITED’, but resetting it to ‘UNLIMITED’ does not work! The syntax that works is:
SQL> alter profile DEFAULT limit password_verify_function null;
The default VERIFY_FUNCTION defined in utlpwdmg.sql is probably not strong enough. For example, it requires only four
characters for the password. This is far too short.
Be aware that in some situations the password verification function may be called when the password is changed with the
SQL*Plus password command, but may be ignored when a password is changed via alter user. Whether this behavior is
dependent on the platform, the Oracle version/release, the name of the function, or the function code is not clear, but the
author has seen it occur. Test to verify that any changes to the value of the profile parameter password_verify_function or to
the function itself work as expected in your environment.
ROLES
Roles play a vital role in database security. Whenever possible, system privileges and object privileges should be granted to a
role and the role granted to individual users, rather than granting privilege directly to individual users. The primary advantage is
of managing a relatively small number of roles versus managing a relatively large number of individual users. In addition to all
the normal privilege management benefits, consider this example:
A database is used for several applications, one of which is APP1. Two roles are associated with APP1 – APP1_USER and
APP1_SUPER. The “create session” privilege is granted to both, but not directly to any user. Some maintenance, perhaps an
upgrade of the APP1 schema, is required that cannot be done with any APP1 users connected. However, we do not wish to
interrupt any other applications running against the database. We can notify all APP1 users of the impending upgrade,
terminate any remaining sessions, and “revoke create session from APP1_USER, APP1_SUPER;”. No new sessions can be
created using this role until we are done and issue “grant create session to APP1_USER, APP1_SUPER;”. (Of course, there
are conditions under which this may not work – for example, some individuals with the APP1_USER role may also have
another enabled role which allows them to create a session.)
- 18 -
Paper #537
DBA
Be aware the grants or revokes of roles (to another role, a user or PUBLIC) are effective only after a set role statement or
when a new session is created. They do not affect connected users already using the role. System or object privilege grants to
or revokes from a role (or user or PUBLIC) are effective immediately.
Roles are disabled inside a definer-rights procedure and any procedures invoked directly or indirectly by a definer-rights
procedure. This is important during the design of roles and during application design.
DEFAULT ROLES
CONNECT is a role, not a synonym for “create session”!
SQL> select privilege from dba_sys_privs where grantee = 'CONNECT';
PRIVILEGE
---------------------------------------ALTER SESSION
CREATE CLUSTER
CREATE DATABASE LINK
CREATE SEQUENCE
CREATE SESSION
CREATE SYNONYM
CREATE TABLE
CREATE VIEW
RESOURCE is a role.
SQL> select privilege from sys.dba_sys_privs where grantee = 'RESOURCE';
PRIVILEGE
---------------------------------------CREATE CLUSTER
CREATE INDEXTYPE
CREATE OPERATOR
CREATE PROCEDURE
CREATE SEQUENCE
CREATE TABLE
CREATE TRIGGER
CREATE TYPE
Although it does not show up here, the RESOURCE role is also granted UNLIMITED TABLESPACE. If the DBA grants
RESOURCE to a user, that user has an unlimited quota on SYSTEM, even after: “alter user SOMEUSER quota 0 on
SYSTEM”! UNLIMITED_TABLESPACE overrides any explicit tablespace quotas. For example, on the same 8.1.7.4 system
that the previous select was run, this test was performed:
SQL> connect system/manager;
Connected.
8 rows selected.
SQL> create user JOE identified by BLOW;
User created.
SQL> grant connect, resource to JOE;
Grant succeeded.
SQL> alter user JOE quota 0 on system;
- 19 -
Paper #537
DBA
User altered.
SQL> connect JOE/BLOW
Connected.
SQL> create table X (c char(1)) tablespace system;
Table created.
SQL> connect system/manager
Connected.
SQL> revoke resource from JOE;
Revoke succeeded.
SQL> connect JOE/BLOW
Connected.
SQL> create table Y (c char(1)) tablespace system;
create table y (c char(1)) tablespace system
*
ERROR at line 1:
ORA-01536: space quota exceeded for tablespace 'SYSTEM'
SQL> connect system/manager;
Connected.
SQL> drop user JOE cascade;
User dropped.
SQL> quit
DBA
DBA is a very powerful role. For the least secure system possible, all one need do is “grant DBA to PUBLIC;”! Granting
DBA to developers and other non-DBA users (even in development systems) is unconditional surrender. It is just a way of
saying “We have no idea what privileges are actually needed, but this should cover all possibilities.” One of many problems
with this is that when migration to production takes place, applications developed in an over-privileged environment will likely
break – they won’t get the DBA role there and the privileges they actually need to function will not have been identified.
DBBS role?
Something else that is sometimes recommended is that the DBA role not actually be used – that only a less privileged
“sanitized “ role be created and granted to the DBA. This has some significant merit, but as a general recommendation may be
security overkill. It is very appropriate for databases or organizations where there may be some less experienced
administrators that actually perform only tasks that require less privilege. It may be appropriate in your system to create such a
sub-DBA role (e.g. DBBS = DataBase Baby Sitter ;-) and use it for day-to-day activity, only invoking the DBA role as needed.
This is a case where password-protecting the DBA is necessary.
Catalog roles - Be particularly aware of which users have been granted any catalog roles.
SQL> select role from sys.dba_roles where role like '%CATALOG%';
ROLE
-----------------------------SELECT_CATALOG_ROLE
EXECUTE_CATALOG_ROLE
DELETE_CATALOG_ROLE
RECOVERY_CATALOG_OWNER
There are a number of other rather privileged roles that may be created with the database. SNMPAGENT,
OEM_MONITOR, IMP_FULL_DATABASE, SELECT_CATALOG_ROLE and several others have some elevated
- 20 -
Paper #537
DBA
privilege. One should establish as a part of the local policy what kinds of users should be granted such roles. Some may be
dropped if not needed.
APPLICATION-SPECIFIC ROLES
The universal and general recommendation is to use roles to manage privileges. A single application-specific role is rarely
sufficient. Other than those simple declarations, we will just say that a detailed discussion of this sort of role usage is as out of
scope here.
ROLES – SHOULD THEY BE PASSWORD
PROTECTED?
This sounds like a “no brainer”, but perhaps the answer is not as obvious as it first appears. If a password protected role is to
be used strictly within the application, no end user ever has to enter a role password, the passwords are stored securely, and the
intent is to restrict the privileges of the role to the normal application interface so the privileges are not present in other tools
(e.g. SQL*Plus, TOD, etc.), then the decision to password-protect the role may be straightforward.
On the other hand, if one or more of these conditions is in question, then password protecting a role may actually be less
secure than just making it a default role with no password. This is considered heresy in security circles where the universal
recommendation is that everything that could possibly have a password should have a password – with no exceptions and
without considering potential consequences. (Externally identifying database users is another victim of this dogma.). Consider
the case where role passwords must be entered by end users. They will likely end up on post-it notes attached to monitors all
over the company. If the role passwords are periodically changed to comply with password policy, then this is even more
likely. In this case, any sense of security from using role passwords is an illusion.
The major advantage of password-protected roles is to restrict the role privileges to the intended application interface. By
transparently setting the role in the application, the user gains the privileges of the role without having to know the password.
Since the user does not know the role password, the privileges of the role are unavailable through other interfaces like
SQL*Plus. Thus the privileges are restricted to known and controlled access. However, if the user must know the role
password, this advantage is defeated entirely – the role may be enabled through the set role command regardless of the interface.
Some sources recommend that literally all roles be password protected – including DBA and other such default roles. To this
author, that seems more like dogma than a well-considered recommendation. Is it really a great cause for concern? Is the
operational complexity tradeoff worth the perhaps minimal security advantage? What exactly might break? What is the cost in
additional time in administrative tasks? If this is determined to be viable in your organization go ahead and do it. Otherwise,
don’t be unduly concerned.
For further information read the documentation, some of the many arguments and discussions on the topic, and perhaps even
the rather provocative perspective titled “Password-Protected Roles: No Security Blanket Here!” by Barry Johnson in the August 1999
issue of Select Magazine:
SYSTEM PRIVILEGES
Grant only what is actually needed.
System privileges should never be granted to the user group PUBLIC.
Severely restrict grants of system privileges with the “ANY” qualifier (e.g. “grant alter ANY table to SOMEUSER;”).
Severely restrict system privilege grants with the “with admin” clause..
Never grant “all privileges” to anybody! This cannot be found in the data dictionary, it is essentially a command shortcut for
(almost) everything in the book!
System privileges except for CREATE SESSION should be restricted to DBAs, database operators, application object owner
accounts and other necessary default accounts in production systems.
Developers may be granted some limited system privileges in development databases.
Ant required system privileges should be granted to roles rather than directly to users.
- 21 -
Paper #537
DBA
Severely restrict system privileges that perform privileged operations. For example, here some of the system privileges that
should be severely restricted:
ADMINISTER DATABASE TRIGGER
ADMINISTER RESOURCE MANAGER
ADMINISTER SECURITY
ALTER DATABASE
ALTER PROFILE
ALTER SYSTEM
ALTER TABLESPACE
ALTER USER
AUDIT SYSTEM
BECOME USER
CREATE LIBRARY
CREATE ROLE
CREATE SNAPSHOT
CREATE TABLESPACE
CREATE USER
DEBUG CONNECT SESSION
DEBUG CONNECT USER
DROP TABLESPACE
DROP USER
EXEMPT ACCESS POLICY
MANAGE TABLESPACE
RESTRICTED SESSION
SYSDBA
SYSOPER
UNLIMITED TABLESPACE
This is by no means a complete list! System privileges with the “ANY” clause, for example, are not included as they should be
severely restricted in general. Most in this list should be restricted for obvious reasons. For some the reason is less obvious.
ALTER USER - Any user (e.g. THISUSER) may “alter user THISUSER identified by NEW_PASSWORD” to change their
own password, even without the ALTER USER privilege. If they have this permission though, they can change their profile,
temporary tablespace, default tablespace, and other attributes they should probably not be allowed to change.
EXEMPT ACCESS POLICY – This may allow a user to bypass fine-grained security.
CREATE LIBRARY – This privilege can be used to access operating system files and gain an escalation of privileges on the
operating system.
Beware that some system privileges may sound innocuous, but have the potential for unintended consequences. For example:
ALTER SESSION – allows things like “alter session set events 'immediate trace name library_cache level 10'”. This can dump
critical data, including other user’s passwords, from the library cache into a trace file.
- 22 -
Paper #537
DBA
CREATE TRIGGER – a user could potentially create a trigger on a table in another schema with unintended consequences.
OBJECT PRIVILEGES
Grant only what is actually needed.
Severely restrict grants of object privileges with the “with grant option”. If an object owner grants privilege on an object with
the “with grant option” and that user then grants it to some third party, the object owner cannot revoke the privilege from the
third party:
ORA-01927: cannot REVOKE privileges you did not grant
In addition, if the privilege is later revoked from the user who was granted the privilege “with grant option”, the revoke has a
cascading effect – it is automatically revoked from all users who were granted that object privilege by that user. This can have
unintended consequences – revoking a privilege from a retiring employee could also revoke it from a number of active users.
Best practice is to allow object privilege grant rights to only the object owner.
Severely restrict object privileges on all data dictionary objects and other objects owned by SYS, SYSTEM and other privileged
users.
SYS.LINK$ may contain passwords in clear text.
SYS.USER$ (and thus SYS.DBA_USERS) does contain hashed passwords.
Many other data dictionary views may contain sensitive information.
Many SYS packages have elevated privilege.
Restrict privileges on the ALL_ data dictionary views if possible.
Revoke unnecessary object privileges from the user group PUBLIC.
Is it really necessary for everyone to have:
Execute on UTL_FILE?
Execute on UTL_SMTP?
Execute on UTL_HTTP?
Execute on UTL_TCP?
Execute on DBMS_RANDOM?
These are packages that are particularly sensitive to abuse. It can be reasonably argued that there are other ways to
exploit the potential vulnerabilities in these packages. However, it doesn’t hurt to lock these particular doors, even if
some others may still not be locked. Sometimes the danger comes from unexpected angles, such as a developer using
one of these inappropriately without even realizing it. At least if they have to ask to have some particular privilege the
DBA has an opportunity to educate them on its usage and potential pitfalls.
Whenever it is possible, grant object privileges to roles instead of directly to users.
This will depend largely on the application security model. For example, if the application uses invoker-rights
procedures extensively, this may not be possible.
SQL*NET/NET8/ORACLE NET
For the sake of brevity, let us use the term “SQL*Net” generically for SQL*Net, Net8 and Oracle Net. When a topic is
relevant for only one of these, it will be so identified.
- 23 -
Paper #537
DBA
If the firewall is the moat that helps protect your database, then the Oracle networking components form the drawbridge.
Before anyone is allowed to cross, they should be identified and perhaps their origin, mode of transport or other information
should be known. Oracle provides the ability to perform these tasks and quite a bit more.
It seems that a high percentage of the Oracle security alerts are for the listener and other networking components.
Vulnerabilities may be due to malformed packets, the submission of exceptionally long usernames and other buffer-overflow
conditions, file permissions, extproc services, and a host of other issues. It is particularly important to keep current on Oracle
network-related alerts and stay patched.
There are a number of naming methods available – local naming, directory naming, Oracle names, host naming, and external
naming. Here we will consider only the most common of these – local naming (using tnsnames.ora). However, most of the
discussion of the listener configuration applies to all of these.
GENERAL CONSIDERATIONS
One question is whether to use netca or perform a manual configuration. Oracle recommends using netca, but one must be
aware of its limitations and idiosyncrasies. Some more advanced options may not be available through netca and some of the
defaults may not be appropriate. For example, in many versions, netca seems limit the port selection to only ports 1521 or
1526. In all recent versions, it creates a extproc listener by default. In most versions, it does not fully support the full
compliment of available options and possible useful configurations for load balancing, failover and some other advanced
features. These kinds of restrictions may limit its usefulness.
A common Oracle security recommendation is to use a listener name other than the default “listener”. This is another
example of “security by obscurity”. Similarly, another common recommendation is to use a port other than the defaults of
1521 or 1526. While a persistent attacker will find the listener on another port anyway, many will not bother looking. (e.g.
Although the attack was not against Oracle, the recent “SQL Slammer” worm looked only at ports 1433 and 1434.)
DEDICATED SERVER VERSUS MTS (MULTI-THREADED SERVER)
There is some debate about this choice in security circle, with the preponderance of the opinions in favor of dedicated servers.
Sometimes the pronouncements are of the form “Don’t use MTS”.. Rather than make any such sweeping generalizations here,
let us examine the differences and see if we can determine on what differences such statements might be based.
DEDICATED SERVER
The client communicates with shadow processes on the listener port. This is true on most platforms at least. The author has
heard on good authority that on Oracle versions on a some platforms, even dedicated server connections are redirected to
other ports, but has not personally verified this.
MULTI-THREADED SERVER (MTS)
9i MTS - client communicates with shared server process on the listener port
Pre-9i - MTS performs port redirection
Client connects to the listener port
Dispatcher assigns some (pseudo-)“random” port above 1024 & informs client.
Client reconnects to new port to communicate with shared server process.
This port redirection is the default behavior prior to Oracle9i. Initially, MTS caused problems as firewalls often
blocked the “new” port. Most firewalls now dynamically open ports for MTS port redirection. However, this is not
particularly well-received by a lot of network security people and some network scanning security software – which
often expect a static set of ports to be open at any given time. The author’s opinion is that this is the major reason for
the “Do not use MTS” recommendations. There are some other considerations though. One is that it is more
difficult to relate client processes using shared servers to other information in the data dictionary views because of
their “shifty” nature! For example, one persistent limitation is the fact that SQL*Trace output for a session is
scattered across the various shared server processes.
- 24 -
Paper #537
DBA
To prevent the “random” assignment of a port, the MTS listener may be directed to use a specific port or set of ports. To
accomplish this, add something like the following to the initialization file (pfile or spfile):
mts_dispatchers="(address=(protocol=tcp)(host=hostname)(port=2450))(dispatchers=1)”
mts_dispatchers="(address=(protocol=tcp)(host=hostname)(port=3125))(dispatchers=1)”
This forces the listener to redirect connections to specific ports - 2450 and 3125.
Note: There are many other possibilities and attributes for this initialization parameter. The pertinent item for this discussion
is the (port=…) clause. Check the documentation for your particular version and platform.
The decision on whether to use dedicated severs or MTS is yours. In situations that may require MTS, it is important to
consider MTS-specific security issues. Either can be made safe with proper configuration.
LISTENER CONFIGURATION
There are several files used to configure the Oracle listener. The configuration files of primary importance are listener.ora,
sqlnet.ora, protocol.ora (8i & prior versions). Some parameters in the initialization file affect how instances register with the
listener and with what service names they register.
EXTPROC
The External Procedure Service (PLSExtProc) is created by default by the Oracle tools (e.g. netca). The signature in
listener.ora is an entry that looks something like:
(ADDRESS_LIST=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC)))
The command lsnrctl status will also reveal an extproc service:
$lsnrctl stat
LSNRCTL for Linux: Version 8.1.7.0.0 - Production on 02-FEB-2003 01:31:57
(c) Copyright 1998 Oracle Corporation.
All rights reserved.
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=anynode.anyorg.com)(PORT=1521)))
STATUS of the LISTENER
-----------------------Alias
LISTENER
Version
TNSLSNR for Linux: Version 8.1.7.0.0 - Production
Start Date
01-FEB-2003 20:05:43
Uptime
0 days 5 hr. 26 min. 14 sec
Trace Level
off
Security
ON
SNMP
OFF
Listener Parameter File
/opt/app/oracle/product/8.1.7/network/admin/listener.ora
Listener Log File
/opt/app/oracle/product/8.1.7/network/log/listener.log
Services Summary...
PLSExtProc
has 1 service handler(s)
TST1
has 1 service handler(s)
The command completed successfully
“The extproc service provides a target-rich environment.” - an Oracle security specialist from NSA
“… a knowledgeable and malicious user can write an exploit that connects to an Oracle Database server’s EXTPROC OS
process without having to authenticate himself. As such, he will be able to make arbitrary calls to the underlying OS and
- 25 -
Paper #537
DBA
potentially gain unauthorized administrative access to the machine hosting the Oracle Database server.” - Metalink Note:
175429.1
These comments alone should raise a large red flag for those with extproc listener services. This service, in its default
configuration at least, allows one to run host programs with the privileges of the Oracle software owner. It is a very dangerous
option and should be completely disabled if not needed. The following steps may accomplish this:
Remove all “extproc”, “icache extproc”, and/or “PLSextproc” entries from listener.ora and tnsnames.ora. Obviously,
listener.ora is much more critical. The listener must be bounced or reloaded after this change to remove the service(s).
Delete or, at least, change the permissions on the executable - $ORACLE_HOME/bin/extproc
If the extproc service is required, one should creating a distinct listener for extproc, on a different port. If at all possible, create
the listener as and make the extproc executable owned by a non-privileged operating system user (e.g. Unix “nobody”). This
may not be possible in some situations. For example, use of iFS may require that the extproc listener be owned by “oracle”.
(The author has not tested scenarios with iFS and some other options.)
For further information, see: http://otn.oracle.com/deploy/security/pdf/plsextproc_alert.pdf and Metalink Note: 175429.1
LISTENER.ORA
The default permissions on this file are world readable. It should have read and write permissions only by the software owner
and the OSDBA group (or perhaps the ORA_INSTALL group instead, in some scenarios). The reason is that weakly
encrypted passwords may be stored in this file. Also, there may be some service names that are for restricted use and should
not be publicly known. It should be writable by the software owner and perhaps by the dba group – depending on local policy.
$ ls -l listener.ora
-rw-r--r-1 oracle
dba
$ chmod o-rwx listener.ora
742 Feb
4 20:12 listener.ora
After modifying the listener with Oracle utilities, a backup file is created (listener.bak, listener.ora.old, listener.ora.001, etc. depending on platform, tool used, and version). Either remove these files or check their permissions and change them if they
are not correct.
The listener should have a password. Actually, all listeners should have a password. A listener.ora file may define multiple
listeners and each may have its own distinct password. The password may be set with the lsnrctl utility and saved to the
listener.ora file.
The perhaps rather humorous example in the “Devastating Accidents” section early in this paper – (“I didn’t know that lsnrctl
stop could shut down the listener on another machine!”) is an example from real life. One does not need to have any
privileges (like rsh) on the database server for this to happen. The communication is through the listener port. The “real life”
situation occurred when a DBA copied the listener.ora file from one machine to another and forgot to change the “HOST=”
entry in the ADDRESS_LIST clause. If the user runs a lsnrctl command, it will attach to the remote listener to execute
command ssuch as status and stop – on the remote listener! Of course, after lsnrctl stop succeeds, lsnrctl start doesn’t work since
the remote listener is no longer running! A listener password could prevent this. An absolutely minimal listener.ora entry is all
that is required to make this remote connection. Something like this will do quite nicely:
LISTENER=DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=anynode.anyorg.com)(PORT=1521)))
- 26 -
Paper #537
DBA
With this example in mind, consider the really significant implication of not having a listener password. If someone can get the
name or IP address of the database server, the port number (1521 or 1526 sound like good guesses), they can shutdown your
listener, show its services, change its settings and generally run amok. Prior to Oracle9i, even if it is password-protected, they
can show its status – and tell if the intelligent agent is running, if a password has been set, if there is an extproc services and
what other services it offers. In Oracle9i (R2 at least), even “lsnrctl status” requires a password.
Some relevant lsnrctl commands:
LSNRCTL> change_password
LSNRCTL> set password
LSNRCTL> save_config
LSNRCTL> set current_listener MY_LISTENER
Current Listener is MY_LISTENER
LSNRCTL> set save_config_on_stop ON
#
#
#
#
Set a new password or change a password
Submit a password!
Manually save the configuration
Set the listener context
# Automatically save the configuration
# when then lsnrctl session ends
The last command here is equivalent to setting “SAVE_CONFIG_ON_STOP_my_listener=true” in listener.ora.
A sample session in the lsnrctl utility (assuming there is already a password):
LSNRCTL> set password
Password:
The command completed successfully
LSNRCTL> change_password
Old password:
New password:
Reenter new password:
Connecting to
(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=anynode.anyorg.com)(PORT=1521)))
Password changed for LISTENER
The command completed successfully
LSNRCTL> save_config
Connecting to
(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=anynode.anyorg.com)(PORT=1521)))
TNS-01169: The listener has not recognized the password
# Note: Since we have changed the password, we need to give the new one now.
LSNRCTL> set password
Password:
The command completed successfully
LSNRCTL> save_config
Connecting to
(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=anynode.anyorg.com)(PORT=1521)))
Saved LISTENER configuration parameters.
Listener Parameter File
/opt/oracle/product/9.2.0/network/admin/listener.ora
Old Parameter File
/opt/oracle/product/9.2.0/network/admin/listener.bak
The command completed successfully
LSNRCTL> quit
The new listener password is now stored in listener.ora:
#----ADDED BY TNSLSNR 01-FEB-2003 18:29:39--ADMIN_RESTRICTIONS_my_listener = ON
SAVE_CONFIG_ON_STOP_my_listener = ON
PASSWORDS_my_listener = 80E31BA5A08D02A6
#-------------------------------------------#----ADDED BY TNSLSNR 01-FEB-2003 19:21:56--ADMIN_RESTRICTIONS_listener = ON
PASSWORDS_listener = F16D80EDE4450DF4
- 27 -
Paper #537
DBA
#--------------------------------------------
The listener passwords are “encrypted”, but how well? Anyone having this information could run an “off-line” brute force
cracking routine to determine the password, then connect to your listener with the password in hand.
Note that “listener”, and “my_listener” here are the listener names.
Note also that parameter names and some parameter values such as ON and off are not case-sensitive.
Note also that ADMIN_RESTRICTIONS_listener = ON. The default is OFF. This is another recommended security setting.
It is most useful if there is no password on the listener, but has an effect even if it there is one. If this is set to ON, it prevents
the runtime modification of parameters in listener.ora. No set commands may alter the running listener. One would need to
modify listener.ora manually and issue lsnrctl reload or issue the set commands from within the lsnrctl utility, save_config and then
reload (reload could of course be stop and then start the listener instead). This parameter appears in the Oracle9i documentation,
but not in the Oracle8i documentation. However, it has been verified to function as expected in several 8.1.7.x versions on
Linux - at least. To determine if it is indeed a valid parameter in your environment, try the following experiment (using the
default listener for the example):
Shut down the listener.
Comment out any lines with PASSWORDS_listener
Add a line with “ADMIN_RESTRICTIONS_listener = ON”.
Restart the listener with “lsnrctl start”.
From the Unix command line, try “lsnrctl set log_status OFF”.
The ADMIN_RESTRICTIONS_listener parameter does nothing if lsnrctl responds with:
LISTENER parameter "log_status" set to OFF
The command completed successfully
The ADMIN_RESTRICTIONS_listener parameter is effective if lsnrctl responds with:
TNS-12508: TNS:listener could not resolve the COMMAND given.
LOG_FILE_listener = <location of listener log file>
Default = $ORACLE_HOME/network.log/listener.log
Whatever the name and location, it should be a protected file in a protected directory.
LOGGING_listener = ON
Default = ON. If listener logging is turned off, some information that might indicate an attack on the listener is unavailable.
8i: CONNECT_TIMEOUT_listener = 2
9i: INBOUND_CONNECT_TIMEOUT_listener = 2
The default for both is 10. This is the time in seconds that a client is allowed to complete its connection request to the listener
after the network connection has been established. If the listener does not receive the client request in time, it terminates the
network connection and logs the IP address of the client and an ORA-12525 to the listener log. The 9i form works in
conjunction with the SQLNET.INBOUND_CONNECT_TIMEOUT parameter in sqlnet.ora. Suggestions in the Oracle
documentation are to set both to low initial values and adjust upward if normal clients are unable to connect within the time
allocated. Without this, a network connection to the listener may stay open indefinitely without even attempting a connection
request. The default is none – there is no limit.
Notes on listener and lsnrctl quirks:
- 28 -
Paper #537
DBA
An invalid control command in listener.ora does not generate an error! For example, adding a totally bogus line like
“DO_NOT_LET_DEVELOPERS_MODIFY_listener = ON” to listener.ora does nothing. All listeners will start
without error. (However, some GUI tools may complain about it!) This is important - if manually editing listener.ora,
test to be sure that the intended changes are effective.
Similarly, some invalid commands, incomplete node lists, syntax errors and the like in sqlnet.ora or protocol.ora also
generate no errors, but will not function as intended. Any modifications to these files should also be thoroughly
tested to be certain that they actually function correctly.
If one changes the listener password to a null string by entering a return at the prompts for the new password in
lsnrctl then the entry in the listener.ora file becomes: “PASSWORDS_LISTENER =”. (The same can be
accomplished by manually editing listener.ora.) Even though there really is no password and commands succeed
without one that would normally require a password if it were not null, the command lsnrctl stat reports: “STATUS of
the LISTENER … Alias LISTENER … Security ON”! The “Security ON” line indicates that there is a
PASSWORDS_listener line in the listener.ora file – even if it is null and ignored!
Anytime that one issues the change_password command in lsnrctl, the new password becomes effective. No further
password-protected commands for the current_listener will succeed until after a set password command followed by the
new password. [A rough equivalent in SQL*Plus would be if a user issued the password command to reset their
password and, upon success, had all their privileges and roles revoked for the current session!]
If a listener is started with a password and the password is set to null while the listener is running, then passwordprotected commands will still require a password until the listener is shut down and restarted or reloaded. One goes
into lsnrctl, issues the set password command, and enters only an <ENTER>, then password-protected command
will succeed in that lsnrctl session. Also, issuing the set password command for a listener that has no password still
requires an “Old password:”.
Listener passwords are case-insensitive. However, if the passwords typed in at the two new password prompts are not
identical, including case, then the result is:
New password:
Reenter new password:
TNS-01110: Mismatch - password unchanged
Another note on listener logging: The listener log should be checked regularly and archived as needed. It may grow to be
rather large. When this occurs, it may slow down connections through the listener as every connection will log some
information – requiring the listener process to append to the log. Also, one usually does not want to keep reviewing the same
information over and over (even with a script). The technique for archiving and clearing the current log file varies a bit
between operating systems. On Unix, simply moving the log file to a new name (e.g. “mv listener.log listener.log.old”) and
creating a new listener.log (e.g. “touch listener.log”) while the listener is running does not work since the file handle is still
pointing to the old file. There are a number of methods to accomplish this. The simplest is to copy the file, then clear it.
However, this may result in a loss of logging information while this is happening. This shouldn’t be a significant problem if it
happens very fast. Possible Unix scripts to do this the simple way are:
cat listener.log >>listener.log.history
ex listener.log <<EOF
1,\$d
wq
EOF
or
- 29 -
Paper #537
DBA
cp –p listener.log listener.log.`date +%j`
cat /dev/null > listener.log
(Note: In Unix, the `date +%j` stamps the archived listener log with a Julian date. Other choices may suit you better.)
Another possibility is to shutdown the listener, rename the log file, and then restart the listener. The listener will generate a
new log file with the old name (e.g. listener.log) when it starts if no such file exists. This is a clean way to recycle the
listener.log file, but no new connections may be established while the listener is down (existing connections are not affected).
Also, if one is using dynamic instance registration, it may take a while for the instance(s) to register with the listener after it
comes up. Here is one example of such a script - for Windows this time. (Note that this assumes that there is no password on
the listener!)
lsnrctl stop
RENAME %ORACLE_HOME%\NETWORK\LOG\LISTENER.LOG OLD.LOG
lsnrctl start
There are a number of more complex and robust scripts available on the Internet that eliminate the possibility of losing any log
information and work on other platforms. In particular, it seems that Windows systems have additional constraints. Oracle
recommends using the lsnrctl set log_file command to redirect logging to a different log file, move the original, then use lsnrctl
set log_file to redirect logging back to the original name. Something like:
lsnrctl set log_file $ORACLE_HOME/network/log/listener1.log
mv $ORACLE_HOME/network/log/listener.log \
$ORACLE_HOME/network/log/listener.log.`date +%j’
lsnrctl set log_file $ORACLE_HOME/network/log/listener.log
However, this also assumes that there is no listener password. In addition there may now be some log entries in listener1.log.
Since lsnrctl set log_file requires the listener password to be entered, it could be automated by generating a lsnrctl script:
# create the temporary lsnrctl command file
echo set password $lsnrpwd > $lsnrcmdfile
echo set log_file $temp_log_name >> $lsnrcmdfile
echo exit >> $lsnrcmdfile
lsnrctl < $lsnrcmdfile
mv $ORACLE_HOME/network/listener.log $ORACLE_HOME/network/listener.log.`date +%j`
echo set password $lsnrpwd > $lsnrcmdfile
echo set log_file $ORACLE_HOME/network/log/listener.log >> $lsnrcmdfile
echo exit >> $lsnrcmdfile
lsnrctl < $lsnrcmdfile
rm –f $lsnrcmdfile
However, this violates a few basic security principles – primarily that passwords should never be stored in clear text. Also, the
variable $lsnrpwd has to be set somewhere. If using a mechanism like this, be sure that $lsnrcmdfile and any other files that
may contain the listener password are protected and kept or created in protected directories.
SQLNET.ORA
Another critical file for listener configuration is sqlnet.ora. This file is created by the Oracle GUI tools, but is not absolutely
required on the server side (for a listener to start) or for the client side (for a connection to be initiated). If it does not exist on
the client, the TNSNAMES name resolution method is assumed. The client may not be able to connect if the tnsnames.ora
entries use a domain name, the sqlnet.ora is not there to provide a value for NAMES.DEFAULT_DOMAIN. And the client
uses a service name without the domain name. There are several critical security parameters here that are not set by default.
- 30 -
Paper #537
DBA
NAMES.DIRECTORY_PATH = (TNSNAMES, ONAMES, HOSTNAME, DCE, LDAP, NIS, NOVELL)
This determines the name resolution order. The list should include only what you actually need.
LOG_DIRECTORY_CLIENT = <some directory not shared or world readable>
The default is the current working directory. Failed connection attempts may possibly generate a sqlnet.log entry with a clear
text password (one such case has been reported to the SANS institute, but tests by this author have been unable to confirm it).
Even without a password, there is likely other information in sqlnet.log that the world should not see. This log directory
should be changed to some protected directory on the client if there is a possibility that a sqlnet.ora file may be generated
somewhere that it may be read by an unauthorized party. As further motivation, setting this generates a single log file in a
known location rather than many log files in many locations.
LOG_DIRECTORY_SERVER = $ORACLE_HOME/network/log/
This is the default. For some versions/platforms it may be the directory from which the listener is started. The directory and
file should not have any world read or write privilege.
NAMES.DEFAULT_DOMAIN = anyorg.com
The default assumption is null. Some Oracle GUI tools will set this to world by default. In Windows, in particular, setting this
to some real value (other than null or world) helps prevent spoofing from another domain.
SQLNET.EXPIRE_TIME = 10
The default is to never expire. This is the time interval in minutes to send probes for dead connection detection. It should be
set to some reasonable on the database server. Idle connections do not get disconnected, but dead connections do.
9i: SQLNET.INBOUND_CONNECT_TIMEOUT = 3
The default is none – there is no limit. This is the time in seconds that a client is allowed to connect with the database server
and provide necessary authentication information. If the client fails to provide the required information in this time, the
database server terminates the connection and logs the client IP address and an ORA-12170 to the server’s sqlnet.log file.
Without this, a client connection to the database can stay open indefinitely. This should be set in conjunction with the
INBOUND_CONNECT_TIME_OUTlistener parameter in listener.ora – and slightly larger.
If using Oracle Advanced Security (formerly the Advanced Networking Option) the configuration parameters for it are also
included in sqlnet.ora.
9i Note: The parameters for protocol.ora described below have been moved to sqlnet.ora in Oracle9i and protocol.ora has
been discontinued.
PROTOCOL.ORA (OR SQLNET.ORA IN ORACLE9I)
These parameters provide a very powerful, but seldom-used security feature – the ability to restrict access to the database
through the listener to a particular set of hosts or to prohibit access from a particular set of hosts.
tcp.validnode_checking=YES
# tcp.excluded_nodes= (hr.com, 202.168.41.12)
tcp.invited_nodes= (appsrvr1, appsrvr2, 207.188.41.12)
- 31 -
Paper #537
DBA
•
The list of invited or excluded nodes may user hostname or network address, or a combination of both.
•
Invited_nodes overrides excluded_nodes if both are present. In short, if invited_nodes is used, only invited nodes are
allowed access. All others are “excluded” – regardless of the value of “excluded_nodes”.
•
These values may be set per protocol. (ipc, tcp, etc.).
•
Wildcards are not allowed!
•
All nodes for a given list must be on one line. On some systems though, this can be a VERY long line! [The author tested
it with Oracle 9.2.0.2 and RedHat Linux 7.2. A single Unix line continuation marker worked in a few situations, but was
neither predictable nor reliable. Multiple line continuation markers never worked – even with short lines. However, an
invited nodes list over 40,000 characters long on a single line that worked as expected every time. The experiment
terminated when the editor crashed repeatedly with a line too long, not when the listener failed to start or to function as
expected.]
In most situations, it is very unlikely that one could really list all addresses/hosts that should be excluded. However, it is quite
often possible to explicitly list all invited nodes.
There are a few bugs with protocol.ora in some versions, on some platforms. For example, Metalink note 90873.1 addresses
issues with Oracle 8.1.5 and Windows and workarounds. In pre-8.1.6.2 Solaris releases one must rename “protocol.ora” to
“.protocol.ora” (note the hidden file name with leading dot/period). If problems occur or it does not work as expected, search
Metalink for a patch or workaround.
If one needs more fine-grained access control (based on source, username, destination, requested service, etc.) or longer lists
than can be had with protocol.ora (or 9i sqlnet.ora) node lists, then Connection Manager is the more powerful alternative.
CLIENT CONFIGURATION
The files of primary importance on the client are tnsnames.ora and sqlnet.ora. Since we discussed sqlnet.ora, including the
client-side parameters, in the previous section, we will discuss only the tnsnames.ora file here.
The most critical decision is to determine what exactly should reside in the tnsnames.ora file on the client machine. It is
prudent to restrict the service names in each client’s tnsnames.ora to only those they actually need. This typically means
creating multiple distinct files for different sets of clients. This can be a configuration management headache in a large and
complex organization – which is why Oracle came up with Oracle Names - and later Oracle Internet Directory (OID).
It should be noted here that the lsnrctl (or lsnrctl.exe) utility and any other unnecessary executables should not be installed (or
should be removed if already installed) from client machines that do no need them. The reason was discussed earlier – all one
needs is an IP address or hostname and a port number to attach to a listener. If the listener is not password-protected, any
such client may shut down the listener or reconfigure it! Even if it is password-protected, the client can still get configuration
information via lsnrctl status. The principle of “install only what you need” applies to the client as well.
Since this paper is primarily about configuring the server, we won’t go far into the evils of passing the client software CD
around and letting developers or end-users do whatever they want – like installing OEM and accidentally building an OEM
repository somewhere!
CLIENT ENVIRONMENT
ORA_ENCRYPT_LOGIN=TRUE (an environmental variable)
The default is FALSE - the password is encrypted for the first attempt, but retries are sent in clear text.
If TRUE, then the password is encrypted for all retries.
Although the Oracle9iR2 documentation contradicts this, this author has heard from informed sources that all retries are sent
with an encrypted password in 9i – regardless of this value.
- 32 -
Paper #537
DBA
Note: If using a client program linked with 7.1 or later libraries to connect to a version 7.0 or earlier database, you may receive
an ORA-01010 if this is set to TRUE. See the error manual for details.
SERVER INITIALIZATION FILE (PFILE OR SPFILE)
DBLINK_ENCRYPT_LOGIN = TRUE
If FALSE, the default, then a database link login will encrypt the password for the first try, then retry with a clear text
password. If this parameter is set to TRUE, the first attempt is encrypted. If it the first attempt fails, there is no retry – the
connection fails. This is a depreciated parameter in 9i. As of 9iR2, at least, all retires are encrypted regardless of this setting.
Beware that even the 9iR2 documentation talks about this parameter as if it has not changed since Oracle8. This is evidently a
documentation bug. Here is what happened in a 9.2.0.2 system on Linux.
With no explicit setting for this in the pfile, the default is:
SQL> show parameter dblink
NAME
TYPE
VALUE
------------------------------------ ----------- -----------------------------dblink_encrypt_login
boolean
FALSE
After setting DBLINK_ENCRYPT_LOGIN=TRUE in the pfile and restarting the
instance. It came up with:
"ORA-32004: obsolete and/or deprecated parameter(s) specified"
because of that setting. However it does change the value:
SQL> show parameter dblink
NAME
TYPE
VALUE
------------------------------------ ----------- -----------------------------dblink_encrypt_login
boolean
TRUE
After setting DBLINK_ENCRYPT_LOGIN=FALSE in the pfile file and restarting the instance. It again came up
with:
"ORA-32004: obsolete and/or deprecated parameter(s) specified"
and again changed the value:
SQL> show parameter dblink
NAME
TYPE
VALUE
------------------------------------ ----------- -----------------------------dblink_encrypt_login
boolean
FALSE
It seems that the parameter is set, a warning is issued on instance start, and it is ignored. The author cannot verify the
latter, but several informed sources state that this is the 9iR2 behavior.
This looks like a documentation bug. Searching all the 9iR2 docs reveals that they all say the same thing they have
always said (since 7.3 at least) about both ORA_ENCRYPT_LOGIN and DBLINK_ENCRYPT_LOGIN. None
mention anything about new behavior or obsolete or depreciated parameters.
REMOTE_LISTENER = <some TNS alias for a set of remote listeners>
This should not be set unless one actually needs the load balancing capabilities in Net8 or Oracle Net. This capability is most
often used in OPS and RAC environments. Failover may be configured in tnsnames.ora without dynamic registration with
remote listeners.
- 33 -
Paper #537
DBA
DBSNMP & THE INTELLIGENT AGENT
The first consideration is - do you need it? If the intelligent agent is not needed, then it should be disabled. If it is needed, it
should be secured. If the database is accessible directly from the Internet, the intelligent agent should be disabled.
TO COMPLETELY DISABLE THE INTELLIGENT AGENT:
1. Remove all jobs and events registered against the database.
2. Stop the intelligent agent if it is running - lsnrctl dbsnmp_stop (or agentctl stop in 9i)
3. (a) Lock DBSNMP’s account or (b) drop OEM_MONITOR and SNMPAGENT roles and DBSNMP user
(a) sqlplus @$ORACLE_HOME/rdbms/admin/catnsnmp.sql - as sys
or
(b) SQL> alter user DBSNMP account lock password expire;
4. Delete the $ORACLE_HOME/bin/dbsnmp executable - or change its permissions to non-executable and remove the
SUID setting. (Note: On some versions this file is owned by root and SUID.)
TO RE-ENABLE THE INTELLIGENT AGENT:
1. (a) Lock DBSNMP’s account or (b) drop OEM_MONITOR and SNMPAGENT roles and DBSNMP user
(a) sqlplus @$ORACLE_HOME/rdbms/admin/catsnmp.sql - as sys
or
(b) SQL> alter user DBSNMP account unlock; -- and set the password as appropriate
2. Restore $ORACLE_HOME/bin/dbsnmp – or change its permissions back to executable.
3. Apply any applicable actions in the next section.
TO SECURE THE INTELLIGENT AGENT:
1. Remove all jobs and events registered against the database.
2. Stop the intelligent agent if it is running - lsnrctl dbsnmp_stop (or agentctl stop in 9i)
3. Change the permissions on $ORACLE_HOME/network/admin/snmp_rw.ora
chmod 700 snmp_rw.ora
4. Secure the catsnmp.sql and catnsnmp.sql files by removing world read permission
chmod o-r catsnmp.sql catnsnmp.sql
5. Change permissions on $ORACLE_HOME/bin/dbsnmp so it is not world executable
6. Change permissions on the dbsnmp executable so the SUID and SGID setting is removed. (chmod –s dbsnmp)
This executable is set GID dba and set UID root in many versions! See: (8)
7. Change the default password and perhaps the username as well
a) Change only the DBSNMP password (e.g. new_password)
I. Edit $ORACLE_HOME/network/admin/snmp_rw.ora to add
snmp.connect.SID.PASSWORD = new_password
for each instance (SID) (database?) the agent is to monitor.
II. Change the DBSNMP password in the affected database(s)
SQL> alter user DBSNMP identified by new_password;
- 34 -
Paper #537
DBA
III. Update the DBSNMP password in $ORACLE_HOME/rdbms/admin/catsnmp.sql
b) Change the username from DBSNMP to something else (new_username)
I. Edit $ORACLE_HOME/network/admin/snmp_rw.ora to add
snmp.connect.SID.NAME = new_username
snmp.connect.SID.PASSWORD new_password
II. Drop the DBSNMP user in the affected database(s)
sqlplus @$ORACLE_HOME/rdbms/admin/catnsnmp.sql - as sys
III. Edit $ORACLE_HOME/rdbms/admin/catsnmp.sql to change the username from DBSNMP to something else
(e.g. new_username) and the password to the new value (e.g. new_password)
IV. Create the new user in the affected database(s)
sqlplus @$ORACLE_HOME/rdbms/admin/catsnmp.sql - as sys
8. Search for and apply any relevant patches
9. Restart the intelligent agent – lsnrctl dbsnmp_start (or agentctl start in 9i)
See: http://otn.oracle.com/deploy/security/pdf/dbsnmp_alert.pdf
Even if your version is not listed, other information may apply.
Search www.sans.org, www.securityfocus.com, www.appsecinc.com, www.iss.net, and/or www.secuiteam.com for “dbsnmp”
for other relevant information.
GENERAL NOTES
The original catsnmp.sql and catnsnmp.sql scripts create and drop, respectively, the DBSNMP user, the OEM_MONITOR
role, and (prior to 9i) the SNMPAGENT role, assign privileges (some of which are quite powerful – like SELECT ANY
DICTIONARY) to these roles and perhaps do some other things like create views, functions and public synonyms. The
catsnmp.sql script first drops the DBSNMP user, then recreates it. This is an extremely important thing to know – the reason
why will become evident in the next paragraph. Please review these scripts for the full details as they may vary substantially
between releases. They are quite different in Oracle8i and Oracle9i.
Whenever the password or username are changed, the catsnmp.sql must be changed to reflect the new username or password.
Since 7.3.3, catsnmp.sql is called by catproc.sql, which is often run by upgrades and occasionally by patches. Since this script
drops and recreates the user every time it is run, the intelligent agent may become unusable if the username and password are
not correct.
Whenever the intelligent agent username is changed, the catnsnmp.sql script should be modified. Otherwise it will not actually
drop the correct user.
If the DBSNMP user’s password is changed from the default, the non-default password must be stored in the
$ORACLE_HOME/network/admin/snmp_rw.ora file in clear text or the intelligent agent will not start. By default, this file
is world-readable (since the software owner’s umask is typically 022).
$ cat $ORACLE_HOME/network/admin/snmp_rw.ora
snmp.contact.listener = ""
snmp.index.listener = 1
SNMP.CONNECT.ORCL9.PASSWORD = mypassword
- 35 -
Paper #537
DBA
Note: “ORCL9” in the above is the database name. There may be multiple similar lines for multiple databases.
The permissions on snmp_rw.ora should be severely restricted, even for read. This is true even if not currently using the
intelligent agent since the DBSNMP password word may still be visible in this file.
The file $ORACLE_HOME/network/admin/snmp_ro.ora should never be modified (“ro” = read only). Permissions should
be restricted to the software owner - and perhaps the OSDBA group.
There are many potential issues with the intelligent agent and with changing the username or password. A search on Metalink
reveals many notes on this topic. A few of them follow. These can be found most easily by performing and advanced search
on “Doc ID”.
70174.1 - How to change the Intelligent Agent USERNAME and/or PASSWORD
Also: 222779.995, 330458.999, and 97068.1 may be of interest.
potential problems and misunderstandings.
They describe some
AUDITING
The idea of database auditing is sometimes greeted by DBAs with a garlic necklace and a raised cross. If not properly
configured and maintained, it can be a very significant problem. The two key issues are performance and space. If one
attempts to audit too much, performance can suffer greatly. The solution is to audit judiciously. The potentially crippling
space issue is because the default location for the audit log in the database is in the SYSTEM tablespace.
Auditing is a very large, complex and somewhat subjective topic. Nobody can assume to be able to advise on exactly what
should be audited in a system unless they have an intimate knowledge of that system. This is an area in which we will cover
some basic configuration issues, skim over a few basics, and forego more detailed discussion.
BASIC CONFIGURATION
The basic setup for auditing will be discussed in some detail. A detailed list of what should be audited, syntax for enabling and
disabling auditing, and a lot of other topics will only be mentioned in passing.
THE AUDIT DESTINATION
This initialization parameter determines into which directory any audit files written to the operating system will go:
audit_dump_dest = ?/rdbms/audit
The above is the default, but OFA suggests $ORACLE_BASE/admin/$DBNAME/adump/. This latter is handy so that all
the “normal” log files for a given instance go to a centralized directory structure. Something like this is be necessary if it is
important to segregate responsibilities for multiple databases sharing an $ORACLE_HOME between distinct groups of DBAs.
It is also useful for simple manageability – all audit logs go into instance-specific directories instead of into a common
$ORACLE_HOME/rdbms/audit/.
DEFAULT AUDITING
Even if database auditing is disabled, some events are always audited. These events are:
instance startup
instance shutdown
connect internal
connect as sysdba
connect as sysoper
connect sys
- 36 -
Paper #537
DBA
This default auditing is always to a filesystem, regardless of the value of the audit_trail initialization parameter. The files are
created in the directory indicated by audit_dump_dest (the default is as described in the previous section $ORACLE_HOME/rdbms/audit/.)
ENABLING AUDITING
As discussed in the section on initialization parameters under database creation, the way to enable auditing is to set the
initialization parameter:
audit_trail = OS | DB | TRUE | FALSE | NONE
NONE is the default, meaning auditing is disabled. The values TRUE and FALSE are only available in Oracle 8.0 and higher.
The values DB and TRUE are functionally identical. For clarity, it is desirable to use DB instead of TRUE since the latter
does not clearly indicate whether it is to the OS or DB.
Simply enabling auditing with this parameter does not actually initiate any auditing actions, it just allows auditing to take place.
One of the most crucial choices that must be made for auditing is whether to keep the audit trail in the database (DB or
TRUE) or in operating system files (OS). Both have advantages and disadvantages. The main advantages of keeping the audit
trail in the database is the ability to use SQL to query, purge, and generally maintain the audit information. Another key
advantage is that Oracle provides a number of data dictionary views that greatly simplify some of the queries against the audit
trail data. The key disadvantage is that the audit information is stored in the SYS.AUD$ table in the SYSTEM tablespace. If
this table grows too large, it may fill the SYSTEM tablespace and cause the instance to “hang”. The procedure for reviving the
instance is not entirely trivial, but is not really complicated. It depends on what is being audited. For example, if one is
auditing successful connections, but the SYSTEM tablespace is full, then one cannot connect normally until after the audit log
is reduced or the tablespace is expanded. These kinds of situations are to be avoided, but if one does chose to audit to the
database, they should be aware of, research and practice the emergency procedures. A search on Metalink should provide the
necessary references.
Another serious consideration here is the possibility of a denial of service attack that intentionally floods the database with
activity that is likely to be audited - invalid connection requests are a prime candidate. An attack like this could fill the
SYSTEM tablespace rapidly.
In the past, Oracle supported and even recommended moving the SYS.AUD$ table out of the SYSTEM tablespace. There are
a number of Metalink notes describing the procedure, mostly for pre-8i systems where the procedure is more complicated.
Although this cannot really be officially recommended practice anymore (see notes following the code example), the mechanics
of moving SYS.AUD$ out of the SYSTEM tablespace is nearly trivial in 8i and 9i.
-- Be sure that auditing is disabled prior to this action!
SQL> select index_name from sys.dba_indexes where table_name = 'AUD$' and owner = ‘SYS’;
INDEX_NAME
-----------------------------I_AUD1
SQL> alter table AUD$ move tablespace AUDIT_DAT
-- With an optional storage clause – and in 9i the online option */
SQL> alter index I_AUD1 rebuild tablespace AUDIT_IDX
/* With optional storage and online clauses in both 8i and 9i */
However, recently Oracle no longer recommends moving SYS.AUD$ since it may cause problems with upgrades and
migrations. Some still do it, but beware that it may be risky and unsupported.
For this reason alone, the best “official” recommendation is to set audit_trail=OS. There is at least one scenario the value OS
is practically required. If the DBA is not the auditor, then the auditor alone should have permission on the audit trail. Robust
protection from the DBA of SYS.AUD$ in the database is nearly impossible, but this sort of protection is simpler when
auditing to the operating system.
- 37 -
Paper #537
DBA
Since this paper is (was?) intended to be an overview and the vast majority of Oracle DBAs will also function as the database
auditor, this author will forego all the prerequisite research necessary to come up with a “cookbook” procedure for this
configuration. The basic concept is that:
The Oracle software owner operating system account must not be routinely used by the DBAs.
The software owner account should be locked at the OS level (optional, but best).
The software owner account must not be accessible by DBAs without supervision by the auditor.
The software owner must have write permission to the audit trail files(s).
The umask for the software owner is such that audit files created in audit_dump_dest may not be deleted or
overwritten by DBAs and the directory itself must not be writable by DBAs.
[… some other constraints…]
This may require that the auditor be given the sole authority to lock and unlock the software owner OS account – or at
least to approve that it be done.
For further information, refer to the Oracle Security Handbook (1) - which has rather detailed information on this rather
complex type of configuration.
WHAT SHOULD BE AUDITED?
Keep it manageable! If you attempt to audit too much, nobody will ever look at it as it will become overwhelming. If you
need an audit trail for a lot of stuff simply for potential after-event forensics or regulatory compliance, but do not intend to
look at it often, consider a frequent archival strategy.
Once auditing is planned and enabled, the next hurdle is deciding what actions need to be audited. There are three general
types of auditing that may be done:
Statement auditing – by type of statement, regardless the object. May be for all users or for specific users.
Privilege auditing – on use of a target privilege. May be for all users or specific users.
Object auditing – on a specific statement on a particular object. Always applies to all users.
Each of these may be audited:
For only successful executions, only unsuccessful executions, or both
Successful executions: “whenever successful”
Unsuccessful executions: “whenever not successful”
Both:
is the default if neither of the above are specified
Once per session or each time executed
The following is a list of items that might be considered essential to audit. This is by no means a complete list of what should
be audited – even at the most basic level. It mainly serves as a sampling of possibilities.
SESSION AUDITING
At a minimum, one should audit failed login attempts. Without this, it is difficult to even tell if someone is trying to break into
the database with brute-force or dictionary-based attacks. If there is some concern about inappropriate usage one might also
wish to audit all connections whether successful or not. Another reason one might wish to audit all connections is to
determine who is in when “odd” activities are taking place.
- 38 -
Paper #537
DBA
SQL> audit session whenever not successful;
or
SQL> audit session;
PRIVILEGE AUDITING
For example, DELETE ANY TABLE is a system privilege. The following statement will audit any use of that privilege when
it fails. This would usually indicate that someone was trying to delete from or truncate a table that did not exist.
SQL> audit DELETE ANY TABLE by access whenever not successful;
SQL> audit ALTER ANY TABLE by access;
STATEMENT AUDITING
SQL>
SQL>
SQL>
SQL>
SQL>
audit
audit
audit
audit
audit
SYSTEM GRANT by access;
SYSTEM AUDIT by access;
ALTER by access
CREATE USER;
CREATE ROLE;
OBJECT AUDITING
Auditing should be done of actions against the audit table itself. This example may be appropriate – or one may choose to
audit only changes to the data:
SQL> audit ALL on SYS.AUD$ by access;
Auditing of critical application tables should be done also. Be careful not to audit too much. Auditing of any changes to
critical configuration data (lookup tables, etc.) and some application data may be judicious. Auditing any access, including read
access, to some very sensitive data (e.g. EMPLOYEE if it includes SALARY) might be required. Auditing of large tables
which undergo a huge transaction load must be done very carefully – and probably not for all users and transaction types.
SQL> audit ALL on HR.EMP_SALARY by access;
SQL> audit delete, insert, update on HR..EMPLOYEE by access;
SQL> audit delete, insert, update on APP1.MASTER_CONFIG by access;
MANAGING THE AUDIT TRAIL
Review the critical audit trail items (e.g. unsuccessful connection attempts, modifications to SYS.AUD$, etc.) often.
Purge or archive the audit trail as needed. SYS.AUD$ is the only SYS table on which Oracle supports direct DML operations
like delete or direct DDL operations like truncate.
CUSTOM TRIGGERS
Consider using row-level triggers if you need very fine-grained auditing to do things like track who is making modification to
critical data, what the before and after values are, and other such details that Oracle auditing does not capture. This can be
used to great advantage – especially for cases like users accidentally messing up your data due to a lack of understanding.
There is often no other good concise way to determine who did what when.
DBMS_FGA
- 39 -
Paper #537
DBA
In Oracle9i there is a new SYS package named DBMS_FGA that allows for more fine-grained auditing. This package may
obtain more information about the user environment, application context and result sets than is possible with the type of
auditing discussed above. It also allows for more selective auditing based on some policy conditions – including data content.
This can significantly reduce the number of “false positives” and the size of the audit trail.
Basic object auditing would allow one to see that some user issued a SELECT against a specific table, but would not capture
the statement or query results and every SELECT statement would generate an entry in the audit trail. DBMS_FGA could
provide a lot more detail about what data was actually queried and returned – and could be configured to audit only a subset of
the selects based on some criteria.
DBMS_FGA may replace some of the auditing functionality that was available only in custom triggers prior to 9i.
If interested in this feature, see: the Oracle9i Supplied PL/SQL Packages and Types Reference.
AUDITING – FURTHER REFERENCES
See: Chapter 26 - Oracle9iR2 Administrator’s Guide (or the appropriate section in earlier releases)
Also, the following is a partial list of Metalink notes related to auditing:
131704.1
207959.1
1019377.6
72460.1
36869.999
82558.996
166301.1
336772.999
1020945.6
1049048.6
167293.1
99137.1
Database Scripts Library Index (!) – including some for auditing
INDEX for Notes on Overview, Setup, Problem/Solutions, Bugs on SECURITY Issues
Script to move SYS.AUD$ out of the SYSTEM tablespace
Moving AUD$ to another tablespace and adding triggers to AUD$
Moving SYS.AUD$ out of SYSTEM tablespace
Moving SYS.AUD$ to another tablespace
How to Reorganize SYS.AUD$ Table
aud$ out of sys ownership (changing ownership of AUD$)
How to Setup Auditing
Auditing with Oracle Parallel Server
Some examples about auditing and output of auditing
Setting up, Interpreting Auditing Using Windows NT Event Viewer
BACKUP & RECOVERY AND DISASTER RECOVERY
Since this is a more general DBA topic, we will only briefly mention a few security-specific aspects of these topics. Assuming
that the backup and recovery plan is well designed and well tested, there are still a few issues that may be overlooked.
Is the backup media protected? Do unauthorized users have access to the backup media? If so, they can recreate your
database, disable all security and read the data.
Is discarded media destroyed? If not a dumpster diver working for some credit card forgery or identity theft ring – or the
competition – may find a gold mine.
Do you have a disaster recovery site? Are all transmissions of sensitive data to that site secure? Are archive logs being sent
over an insecure network t the standby database? Is replication running over an insecure network? Is the 3rd party off-site
storage facility secure?
- 40 -
Paper #537
DBA
APPLICATION DESIGN AND RELATED TOPICS
What follows are only a few very simple samples of the many topics in this area. The topics included are those that the author
deems to be some of the most common and most serious issues. None should be considered even remotely comprehensive in
treatment of the subject.
BASIC DESIGN ISSUES
During the first phases of the application cycle, it is important to gather security requirements for the data. Once this is done,
the application design needs to be cognizant of the security requirements and incorporate security-related elements as well as
the usual functional elements. If this is not done up front, it may be impossible to accomplish later via retrofit. A security
model should be developed early in the lifecycle. Some of the key considerations in the various phases are:
Analysis and design
What account(s) will own the application and/or data? (Some might own stored objects, but not tables.)
Application owner account(s) should NOT be used for any access other than (perhaps) schema changes.
Application owner account(s) should be locked at all times except for these maintenance activities.
How are these roles enabled?
By default?
By password?
User supplied?
User-transparent and supplied by application? (Securely stored? Encrypted?)
What stored procedures (including functions and triggers) will be:
Definer-rights procedures?
Invoker rights procedures?
What roles are required and what privileges do they need?
Classify the types of users and build application-specific roles to bundle the appropriate privileges.
One single role is rarely appropriate. APPUSR alone is seldom sufficient from a security perspective.
Which tools/interfaces will access the data?
Many have no client-side security
Some have no capabilities in a secure environment.
Some demand severely over-privileged access even for simple task (e.g. SELECT_CATALOG_ROLE, etc.)
Some require special consideration in the design of other app components and database configuration.
Can PRODUCT_USER_PROFILE be used to restrict SQL*Plus commands?
Will the application authenticate users and connect to the database as the dreaded “One Big User”?
If so, auditing and authorization are largely meaningless!
How does this work if the user is connecting through some other interface (e.g. SQL*Plus, etc.)?
How will batch-oriented programs be run?
What account will they use?
How will passwords be supplied?
What data needs to be encrypted?
How strong does the encryption need to be?
Who will have access to decryption routines?
- 41 -
Paper #537
DBA
How will the key be stored?
Are public synonyms needed? (Are they REALLY needed or just easier?)
What are the performance implications
What are the security implications?
What if any database links are needed?
Private or public?
Fixed? (hard-coded passwords?)
What are the availability and recoverability goals?
What are the system availability requirements?
What are the backup and recovery requirements?
What are the disaster recovery requirements?
Development/coding
Source code version controls?
SQL Injection possibilities?
Dynamic SQL
PL/SQL
Is the development database ever populated with some sort of production data? (DB clone, export, etc.)
Has sensitive data been sanitized?
Have production passwords been changed?
Is testing thorough?
If not, developers will be into PROD a dozen times a day to “fix” things and PROD security becomes null
Who says so? Who decides when code or schema changes are “done”? The developers with tunnel vision?
Deployment
What are the backup procedures?
Who is responsible for account maintenance?
What user accounts are needed?
What roles does each user or class of users get?
What are appropriate profiles for the users?
Developer accounts are not allowed in production!
Developers are not given the production application owner passwords.
Batch programs
Who, what, when, where, and how. (Perhaps “why”, but that should have been a design issue!)
Has the DBA reviewed all batch-like programs for possible and rather common accidental DoS?
Rollback extend failure
Temporary tablespace full
Inappropriate locking
System saturation – CPU, I/O, etc.
The infamous daily job that takes 28 hours to run?
Is there a deployment plan?
Has the DBA reviewed and approve all the DDL?
- 42 -
Paper #537
DBA
What application/data owner accounts need to be unlocked and for what activity?
What new database or software options are needed?
Maintenance
How do obsolete data, tables, stored code, and other objects get purged?
Database links between PROD and DEV (either way) are not allowed!
Development is NOT allowed against production systems – ever.
Ad infinitum…
This is actually the short list! In reality, many of the items from each earlier phase need to be included in some later phase also.
For example, most of the deployment items are also pertinent to the maintenance phase. Things like the issues with passwords
and sensitive data when cloning the production database to create a new development database belong in any phase in which it
might occur.
VIEWS
Views may be updated. If you intend a view to be read only, define it to be so by adding the “with read only” clause at the end
of its definition.
If a view is to be updateable, but it’s where clause is to be enforced on update, delete, and insert, then use ”with check option”
at the end of its definition. Otherwise, the restrictions in the where clause may be ignored. The exact behavior varies a little –
with some releases/scenarios only “out of bounds” inserts are allowed and on others such updates and deletes are possible as
well. The basic behavior is easily demonstrated by example:
SQL> select * from dept;
DEPTNO NAME
------ -------------------1 ACCOUNTING
2 RESEARCH
3 DEVELOPMENT
SQL> create view dept3 as select * from dept where deptno = 3;
View created.
SQL> select * from dept3;
DEPTNO NAME
------ -------------------3 DEVELOPMENT
SQL> insert into dept3 values (0,'HACKERS');
1 row created.
SQL> create or replace view dept3 as select * from dept where deptno=3 with check option;
View created.
SQL> insert into dept3 values (9,'DATABASE');
insert into dept3 values (9,'DATABASE')
*
ERROR at line 1:
ORA-01402: view WITH CHECK OPTION where-clause violation
- 43 -
Paper #537
DBA
SECURE PL/SQL WRAPPER
Wrapping your PL/SQL code helps prevent several types of potential problems. Competitors cannot read wrapped code.
Also, it is a bit more difficult for people to make ad hoc modifications – especially through tools like TOAD. Wrapping code
is simple and the only real penalty is that it takes more space. One does not want to store wrapped code in a source code
control system, so the common procedure is to pull the code, wrap it, then distribute the wrapped code for implementation.
The syntax is:
wrap iname=<file with plain text code> oname=<file with wrapped code>
Note that this wraps the code only. When run, it does not obscure variable values and other potentially sensitive information
that could be retrieved from the instance or trace files.
DEFINER’S RIGHTS VERSUS INVOKER’S RIGHTS
Stored procedures and packages may be declared to run using the privileges of the owner (the definer) or of the user running the
code (the invoker). Definer rights is the default, but may be changed with the AUTHID clause as in this example.
create procedure CREATE_DEPT (
my_deptno number,
my_dname varchar2,
my_loc varchar2) authid CURRENT_USER as
begin
insert into DEPT values(my_deptno,my_dname,my_loc);
end;
The choice is a design issue and hinges upon the security model for the application. The Oracle community has been
discussing this for years, so there is a lot of material and a lot of opinions on the subject.
For further information, see the Oracle documentation and perhaps some other sources such as:
http://www.oracle.com/oramag/oracle/00-Jan/index.html?10O8i.html - The Right Stuff: Invoker-Rights Procedures
DYNAMIC SQL
Beware of the potential for SQL injection attacks, especially in web applications that use dynamic SQL. A SQL injection
attack is exactly what it sounds like – someone injecting SQL that was not intended as part of the application. The most basic
form of such vulnerability comes from an application that simply accepts whatever the user enters, builds a string using these
values, and passes it on to the database for execution without validating anything – neither the content or the length of the
input values. Both may cause serious problems.
For example, if the developer knows that a single quote mark or some other special characters should never appear in a string,
then the string should be checked by the application and any such characters filtered out – before anything is passed to the
database. Many SQL injection attacks are based on the technique of entering a single quote mark and then some additional
text. For example, if an application password field on a screen is not checked, one might enter something like:
XXXX’ or ‘a’ = ‘a
Into the password field on the screen. If all the application does is build a string for the SQL and send it off unchecked, and
wait for a return code, then the resulting string might look something like:
select 1 from app_user where username=‘username_entered’
and password=‘XXXX’ or ‘a’=‘a’
- 44 -
Paper #537
DBA
If the developer knows that some particular values should never exceed some particular length, then input that exceeds that
length should not be allowed. Another common ploy in SQL injection attacks is to append some additional text to the query
so as to retrieve data that is not intended. For example, adding something like:
vacation‘ union select name, salary from employee where ‘X’ = ‘X
could result in a query against the HR database that ends up looking like:
select ‘vacation hours accrued: ‘, remaining from employee_time_accrual
where employee = ‘JOE’ and type = ‘vacation’
/* as intended */
union select name, salary from employee where ‘X’ = ‘X’
/* NOT INTENDED! */
Granted, these are rather trivial and artificial examples – and perhaps not even exactly correct. The point here is to illustrate
the principle. To protect the data, such items should be considered when the application is designed and when the code is
written. It may take some extra time to design the application to be secure, perform input validation checks, minimize use of
dynamic SQL, or whatever is required to protect the data and the system, but the cost of not doing so may be much greater.
This is barely the tip of the iceberg for SQL injection or how to protect against it. There are many sources for further reading
on this topic. A few are listed in the reference section. Pete Finnigan has an excellent two-part series on Oracle SQL injection
at www.petefinnigan.com – also available at:
http://online.securityfocus.com/infocus/1644 – SQL Injection and Oracle, Part One
http://online.securityfocus.com/infocus/1646 – SQL Injection and Oracle, Part Two
While not really SQL injection, there is another reason to validate input. Many buffer-overflow attacks are based on things like
exceptionally long usernames, exceptionally long passwords, and the like. If the program does not allow values that exceed
normal limits, then these types of attacks may be prevented also – at least through that particular program.
ENCRYPTION
IN THE DATABASE
What, if any, data should be stored encrypted in the database? Any particularly sensitive data is candidate – credit card
numbers, social security numbers, PINs, etc. What constitutes sensitive data is very subjective. Should developers,
administrators, and others have the ability to read this data? The decision is yours. Encryption obviously complicates the code
and application design, but consider the number of times that some company has made headlines because someone hacked
into a system and obtained a few hundred thousand, or a few million, credit card numbers. One might at least audit any
retrieval of such information.
If data is to be stored encrypted, then the question becomes “where should the data be encrypted?” If the data is encrypted
and decrypted at the database level, then it may still be traversing the network in clear text.
Although any significant examination of encryption is definitely out of scope for this paper, a few other key considerations are:
How strong does the encryption algorithm need to be?
How are the keys managed?
Is decent one-way hashing sufficient?
For something like PINs for customers on a web site, it probably is. The PIN can be converted with a oneway algorithm. Any subsequent PIN entry can be converted with the same algorithm and compared to the
stored hash value.
For anything that needs to be converted back to an unencrypted value, a one-way algorithm is insufficient.
- 45 -
Paper #537
DBA
ACROSS THE NETWORK
Should the data across the network be encrypted? The ORA_ENCRYPT_LOGIN environmental variable and the
DBLINK_ENCRYPT_LOGIN initialization parameter that we talked about earlier do not force the encryption of data – they
affect only passwords. If there is a possibility that someone with malicious intent, from inside or outside, might be able to
capture packets flowing across the network then the possibility needs to be considered. If sensitive data is being passed
through a less than ultra-secure network via Net8/OracleNet, then the Oracle Advanced Security (OAS) option might be
essential.
A few extremely security conscious organizations actually have a very stringent policy that NO network traffic behind the
firewall may be encrypted! These are places that have staff whose job is to monitor traffic to see if inappropriate information
may be going to unauthorized destinations.
HIDING PASSWORDS
This is really a general topic, not one specific to application design and development. The general issue is whether passwords
are revealed to the operating system. This applies to host commands, scheduled jobs (e.g. cron), and all other such sources.
One should not imbed passwords in cron jobs, scripts, environmental variables or any other files. However, one must
sometimes be able to run jobs when there is nobody around to type in a password.
For example, from the command line one may issue:
$ sqlplus scott/tiger @script.sql
This may reveal the password to anyone on the host. A simple test with Oracle 8.1.7.4 on Solaris 8:
$ ps –ef
scott
7893
7883
1 15:50:01 pts/7
0:00 sqlplus scott/tiger @script.sql
This same test, using Oracle 8.1.7.4 on a RedHat Linux 7.2 showed only:
$ ps –ef
scott
32529 32488
0
08:47 pts/2
00:00:00 sqlplus
Even though this is very dependent on the system, one should not assume that this test alone is sufficient to insure that
nobody can read the password. The best practice is to simply never reveal a password where it might be intercepted or read in
such a fashion.
There has been a lot of discussion over the years about how to deal with this issue. Many potential solutions have been
suggested and commonly adopted. Some almost work and some actually work. Some that actually work are more secure than
others.
For example, one “solution” that almost works is to build a very long command string with the password far to the right. The
idea is that a command like “ps” and similar commands will be unable to see the password since only a certain number of
characters are visible – the remainder will be off the right edge of the screen or simply not echoed by the command. The
problem with this one is that many common tools can still reveal the password. Metalink Doc ID: 1009091.6 contains a
program named “hide.c” that uses this method.
Another method that is a little better is to store a password in an environmental variable then issue a command like:
- 46 -
Paper #537
DBA
$ sqlplus scott/$MYPASSWORD @script.sql
However, environmental variables are not all that secure either. Someone may be able to read the file that sets the
environment or find some other way to see the value.
Yet another common technique is to create a file (e.g. .connect.txt) containing something like “scott/tiger” and make the first
line of script.sql look like “@.connect.txt”. This is better, but doesn’t work very well in some situations. Variations on this
them that insert a password into script.sql via substitution are usually much worse as scripts tend to get left about the system
with clear text passwords imbedded.
Another solution is to store one or more passwords in clear text, but in a file readable only by the owner. For example, in
Unix one can create a hidden file (e.g. .mypwd) containing the password. If this file resides in a hidden directory (e.g.
$HOME/.hidden) where only the owner has any permission (e.g. chmod 700 $HOME/.hidden) and only the owner has
permission on the file (e.g. chmod 600 $HOME/hidden/.mypwd), then this is fairly safe. To use this, the owner needs an
executable script to fetch the password and pass it on that also is hidden and readable and executable only by the owner (e.g.
chmod 700 .getpass). The .getpass script might only fetch the password (e.g. “echo $HOME/.hidden/.mypwd” ). Then the
command line becomes something like:
.getpass | sqlplus scott @script.sql
This can be modified to use several username password combinations and pass on a password based on a command line
parameter for the username. For example, mypwd might look like:
scott tiger
adams wood
and the script .getpass might look like:
fgrep $1 $HOME/.passwd | cut -d" " -f2
Then the command would look like:
.getpass scott | sqlplus scott @script.sql
While some of these are better than others, all have flaws. Passwords stored in clear text in any file are still subject to being
read by a skilled or privileged user. In addition, as passwords are changed, these files need to be updated.
A better solution is to only store passwords encrypted and build routines to retrieve and decrypt them as needed. These tools
may be external to the application or, better yet, internal routines. They may also perform some additional authentication
and/or authorization checking.
For example, role passwords in applications should be treated in this manner. The end user never enters or sees the password
and it is not stored in clear text anywhere that an unauthorized user might see it. This still does not solve the issue of
maintenance when changing passwords though.
One last note here is that externally identified accounts do avoid all these problems. Some security sources say that externally
identified database accounts are inherently bad – that all database users should always be forced to supply a password. This
- 47 -
Paper #537
DBA
author respectfully disagrees – and classifies this statement under “security myths and folklore”. Externally identified accounts
are especially useful for batch-like system jobs that require some privileged access – online backups (if using homegrown
scripts at least) and other such jobs initiated from the host. If one of the OSDBA accounts or the software owner account are
compromised, does it really matter much that the intruder can connect to the instance with “sqlplus /” without a password?
They would likely succeed with “sqlplus ‘/ as sysdba’, svrmgrl, or something similar anyway. In the vast majority of cases, they
could quite easily destroy or steal the database even without instance access!
Perhaps the best method to avoid all these issues for many activities is to simply not initiate them from the host. For this,
DBMS_JOB can be very handy. It may impose some additional security considerations, but we will consider this discussion
out of scope here.
PHYSICAL SECURITY
What constitutes sufficient physical security? This topic is out of scope here, but Oracle database servers have been found
sitting in an unlocked closet at a retail store, on a shelf in a men’s restroom (!), the kitchen of a restaurant, and other absurdly
insecure locations. No amount of rigorous locking down of the listener, the DBA account, application privileges, and all the
other things we have seen discussed here will do much good if someone can walk off with the server or knock it off a shelf.
NOTES ON “EXPERT RECOMMENDATIONS” AND SECURITY SCORING SOFTWARE
There are quite a few excellent sources of security-related material for Oracle. However, be fully aware that one should never
accept any recommendations as gospel and implement them without due consideration and testing – including the recommendations
in this paper! What may work without problem in 99.9% of the systems out there may make your system completely unusable!
Database systems are usually the most complex, variable and enigmatic of all and they protect the most valuable assets of the
organization. Any significant modifications should be thoroughly tested prior to implementation in any critical environment.
Even if some recommendation is approved by every authoritative source and seems harmless, it is up to you to determine if it
is appropriate in your environment.
Beware that generic security experts often make Oracle security recommendations that seem to be based on dogmatic
adherence to purist principles and generated from research of individual components in isolation, but that are absurd as a
whole in the real world. An example is that the author has seen several sources that say one must “remove the svrmgrl
executable for the server” and “remove the sqlplus executable from the server” – and that failure to do either of these
constitutes a “severe security risk”. Even if nobody, including the DBA, is supposed to ever access the database from the
server, how does one start or stop an instance? Automated instance restart on a Unix sever when the system is started
becomes impossible. Is all administration supposed to be done remotely? Apparently not since the same sources usually say
that such remote administration, via OEM for example, is also expressly forbidden and another “severe security risk” (e.g.
“thou shall” set REMOTE_LOGIN_PASSWORDFILE = NONE).
Be aware also that even some of the most outstanding, knowledgeable, and well-meaning Oracle security experts sometimes
make recommendations that simply do not work when taken as a whole. One such example is this combination of
recommendations (paraphrased):
1) The software owner account must be locked and used only for software installation, upgrades, & patches.
2) Ensure that the permissions on trace files are such that only the software owner can read them.
3) Ensure that the directory used for background_dump_dest is readable only by the software owner.
4) Regularly review and archive the alert log
5) Regularly check for trace files that may be generated in background_dump_dest
6) Regularly check for trace files that may be generated in user_dump_dest
- 48 -
Paper #537
DBA
Each of these in isolation may sound reasonable (this author disagrees with 2-3, thinks that 4-6 are essential, and that 1 should
perhaps be optional – depending on the circumstances). However, in combination they form a logical contradiction. If 1-3 are
followed religiously then, by definition, 4-5 are literally impossible. This is obviously not what was intended.
A corollary to this is that all known security scoring software checks each element in isolation, scores that element, then adds
up all the individual scores to determine an overall rating. Given that the recommendation sets that these scoring tools are
based on always contain the sort of contradictions illustrated above, no system ever receives even near-perfect scores. Even the
most secure systems imaginable typically score 80%-90%. If all the items above were discernable by a scoring program, no
system could ever do better than 50% (assuming they are all equally weighted). If management sees that some system scores
only 50% on a security scan they will likely want to know why – and demand that it be “fixed”. The only way to actually “fix”
something like this is to change the requirements (e.g. in the example - modify constraints #2 and #3 – or drop constraint #1).
Even the experts agree that the important thing in any such security assessment is not the score, but the improvement in the
score between an initial assessment and a subsequent assessment – after “weaknesses” have been identified, analyzed and
remedied as necessary.
CONCLUSION
Hopefully, this discussion has helped those with minimal database security experience understand some of the issues. Even
the experienced may have found something here that is new, a different approach or at least challenges the conventional
wisdom.
If one follows every reasonable expert recommendation, installs every conceivable security-enhancing patch and option – for
the network, the system, the database, and the application – and configures everything correctly, does this mean they are
invulnerable? No! There are certainly yet-unknown vulnerabilities and very imaginative hackers out there. Furthermore, the
next major security hole may only be one application code update, one OS patch, or one Oracle release or patch away. Stay
vigilant!
RESOURCES:
HIGHLY RECOMMENDED READING
Oracle Security Handbook by Marlene Theriault & Aaron Newman, Oracle Press 2001 ISBN: 0-07-213325-2
Oracle Security: Step-by-Step by Pete Finnigan – available at http://store.sans.org
The Oracle documentation! – http://otn.oracle.com/documentation/content.html
GENERAL
otn.oracle.com/deploy/security - Oracle’s security site
otn.oracle.com/deploy/security/alerts.htm - Oracle security alerts & subscription to notification service
www.cisecurity.org - The Center for Internet Security (CIS)
www.sans.org - SANS Institute (SANS: SysAdmin, Audit, Network, Security)
www.appsecinc.com - Application Security Inc (Aaron Newman)
www.pentest-limited.com - PenTest Limited (check out “Downloads” and “Technical Papers”)
online.securityfocus.com - Search for “Oracle” – Advisories, etc.
www.petefinnigan.com - Pete Finnigan (Look at the “White papers” menu -> Oracle Security
ARTICLES, PAPERS, & SCRIPTS
downloads.securityfocus.com/library/oracle-security.pdf
Exploiting and Protecting Oracle – Pete Finnigan 2001
- 49 -
Paper #537
DBA
lists.jammed.com/pen-test/2001/08/0138.html
Revealing Clear Text Passwords from the SGA – Pete Finnigan
www.oracle.com/oramag/oracle/00-Jan/index.html?10O8i.html
The Right Stuff: Invoker-Rights Procedures – Jason Couchman
www.pentest-limited.com/default-user.htm
A list of default users and passwords
www.pentest-limited.com/check_users.sql
Script to check for default passwords
www.dbatoolbox.com/WP2001/dbamisc/how_to_write.pdf
How to Write an Oracle Security Plan - Marlene Theriault & William Heney – 2000
www.dbatoolbox.com/WP2001/dbamisc/misc_how_i_broke_in.pdf
How I Broke Into Your Database – Kevin Loney - 1998
www.kevinloney.com/free/otrace.doc
How and Why to Disable Oracle Trace - Kevin Loney
www.kevinloney.com/free/alterpwd.doc
How to Facilitate Oracle Password Changes - Kevin Loney and Rachel Carmichael
www.kevinloney.com/free/alterpwd.doc
How to Generate Password Expiration Warnings - Kevin Loney and Rachel Carmichael
www.dbatoolbox.com/WP2001/dbamisc/misc_protect_I_site.pdf
Protecting Your Internet Site Before Disaster Strikes – Marlene Theriault 1999
home.earthlink.net/~adamshalon/oracle_password_cracker/
A simple Oracle password cracker
www.sans.org/rr/appsec/net_safe.php
Making Your Network Safe for Databases – Duane Winner
www.crtinc.com/pls/prod/docs/FOLDER/ORATECHS/DOCS/ORATECHS/JOHNSON.PDF
Security by Design: What No One is Telling You
www.hotsos.com/dnloads/0.Millsap1995.09.24-OFA.pdf
- 50 -
Paper #537
DBA
The OFA Standard – Oracle for Open Systems
www.sans.org/rr/appsec/net_safe.php
Making Your Network Safe for Databases
- 51 -
Paper #537