Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Microsoft Access wikipedia , lookup
Concurrency control wikipedia , lookup
Microsoft SQL Server wikipedia , lookup
Microsoft Jet Database Engine wikipedia , lookup
Relational model wikipedia , lookup
Open Database Connectivity wikipedia , lookup
Database model wikipedia , lookup
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