Tyler Muth’s Blog

Technology with a focus on Oracle, Application Express and Linux

Archive for the 'Security' Category


Wrap and compile in one step

Posted by Tyler Muth on September 14, 2007

The PL/SQL wrap utility is a great way to obfuscate code that you do not want anyone to view. Typically this is used for security functions Virtual Private Database and Fine Grained Auditing policies, encryption and hashing functions, and authentication and authorization procedures. The source of unwrapped code can easily be retrieved from the ALL_SOURCE view or almost any IDE that connects to the database.

Prior to 10g, you needed to use the command-line wrap binary located in $ORACLE_HOME/bin. This was a 2 step process, requiring you to first wrap the code from the shell, then compile it using SQL*Plus. 10g introduced the DBMS_DDL package, allowing you to wrap code from within PL/SQL and compile it in one step. This means you don’t need to be on a machine where Oracle is installed, allowing you to use other tools such as APEX and SQL Developer to wrap your code.

Here’s a quick example:

-- Run the following grant as sys:
-- grant execute on dbms_ddl to demo;
declare
  l_function    varchar2(32767);
begin
  l_function := q'!
    create or replace function wrap_test
      return varchar2
    is
    begin
       return 'Yep, it worked';
    end wrap_test; !';
  -- Toggle the comments on the following 2 lines to toggle wrapped / not wrapped
  -- execute immediate l_function;
  sys.dbms_ddl.create_wrapped(l_function);
end;
/

Here’s a screenshot of the wrapped source code in SQL Developer:
Wrapped Code

References:

Posted in Oracle, Security | 1 Comment »

RMAN Encrypted Backups

Posted by Tyler Muth on September 8, 2007

A number of recent high profile data thefts have resulted from lost or stolen backups that were not encrypted. Offsite backups are a good first-step in a Disaster Recovery plan, but they also create a huge risk for data theft. Even if the backup is not offsite, a backup sitting around your office represents nicely packaged target for someone to steal. If you need a reality check, take a look at some of the events listed on the Chronology of Data Breaches:

  • Bank of America: Lost backup tape, 1,200,000 records
  • Ameritrade: Lost backup tape, 200,000 records
  • Time Warner: Lost backup tapes, 600,000 records
  • CitiFinancial: Lost backup tapes, 3,900,000 records

Encrypted backups provide a huge improvement in security without having to change your application code or database structures. Obviously, sensitive data stored unencrypted in the database is still a problem, but it’s typically a much more challenging problem to solve. More on that issue in future blog posts…

Oracle offers several solutions to encrypt backups. Oracle Secure Backup is designed for direct backups to tape, offers several options for encryption, and even comes in a free “Express” version for tape devices directly attached to a single server. Starting with 10gR2, RMAN can also encrypt backups to disk when used in conjunction with the Advanced Security Option (ASO) for the database. I’m only going to cover the RMAN solution in this post since I don’t have access to a tape device.

RMAN encryption can either use a password, an Oracle Wallet, or both as keys to encrypt a backup. If you choose to use both a wallet and a password to encrypt, you only need to one of the keys to decrypt your backup. So, choosing to use both options doesn’t make your backup more secure, it simply allows you to use either method for decryption in case you lose the wallet or forget the password. The beginning of this article on TDE provides a simple example of configuring a wallet. For more detailed information, here’s a link to the documentation for RMAN Encrypted Backups.

The following 5 minute screencast demonstrates RMAN encrypted backups, first using Enterprise Manager Database Control, then in more detail using the RMAN command-line interface.

ScreenCast Click here for the full-size version

Code

Unencrypted Backup:
rman target /
configure channel device type disk format ‘/backup/%N_%s’ maxpiecesize 2 G;
backup tablespace test1 tag=unencrypted;

Password only Encrypted Backup:
rman target /
set encryption on identified by ‘L!eFLW@Bf=U,ptC>’ only;
backup tablespace test1 tag=encrypted;

Password and Wallet Encrypted Backup:
rman target /
configure encryption for database on;
set encryption on identified by ‘L!eFLW@Bf=U,ptC>’;
backup tablespace test1 tag=encrypted;

Restore Tablespace from Backup:
rman target /
sql ‘alter tablespace test1 offline immediate’;
set decryption identified by ‘L!eFLW@Bf=U,ptC>’;
restore tablespace test1;
recover tablespace test1;
sql ‘alter tablespace test1 online’;

Posted in Oracle, Security | 3 Comments »

Oracle Wallet w/ Self-Signed Certificate

Posted by Tyler Muth on July 27, 2007

I was working with some of the security tools included with the Oracle Advanced Security Option and wanted to create a new wallet without going through the hassle of requesting a certificate from one of the popular certificate authorities. After struggling a bit with creating a self-signed certificate, I found a great HowTo by Jim Coulter entitled “How To Build an Oracle Wallet with OpenSSL”. Since I’m planning on a number of future security posts that rely on the Oracle Wallet Manager, I wanted to repost Jim’s HowTo here so they would all be at the same location. Just to be clear, this is NOT my HowTo, it’s Jim’s and I want to give him full credit for a very concise and accurate HowTo.

This HowTo is relevant for any Oracle component that uses the Oracle Wallet Manager, including the Oracle Database with the Advanced Security Option (ASO), Oracle Application Server, Oracle HTTP Server (OHS), Oracle Internet Directory (ODI). For production environments, you should purchase a certificate from a well known certificate authority such as Entrust, Thawte, GoDaddy, or VeriSign. Using self-signed certificates provides no protection against man in the middle attacks so they should NOT be used in production environments.

Even though the example is Linux / Unix centric, I also tested this on Windows using CygWin and it worked flawlessly.

From Jim Coulter’s site, with one addition:

  1. Download and unpack the ssl helper scripts named ssl.ca-0.1.tar.gz from the OpenSSL > Contributions page.
  2. Open Oracle Wallet Manager and create a new wallet and certificate request.
  3. Export the certificate request to a file. Give it a .csr extension
  4. Move the certificate request to the directory containing the openSSL certificate authority scripts (e.g. /usr/src/crytpo/openssl/apps/ssl.ca-0.1)
  5. Create a self-signed root certificate by running the new-root-ca.sh script. This will create a file called ca.crt
  6. Create the self-signed server certificate by running the sign-server-cert.sh script, e.g. # sign-server-cert.sh <certificate-request-filename>. This will create a file called <certificate-request-filename>.crt
  7. Import the ca.crt into the Oracle wallet as a trusted certificate. Import the <certificate-request-filename>.crt as a user certificate.
  8. Enable auto-login and save the wallet. It is now ready for use.

References:

Posted in Oracle, Security | 11 Comments »

Fine Grained Auditing

Posted by Tyler Muth on June 26, 2007

Below is a short screencast (code in action, no PowerPoint) of Fine Grained Auditing in the context of Application Express. It’s in response to this article, which only dedicates a single sentence to the topic of trip-wires, but I do credit them for raising the issue. The code is posted below the screencast. Other things to keep in mind:

  • This policy will fire for every insert,update,delete, or select statement for this table, but not every row
  • It would be easy to defeat this policy by setting module yourself and logging in as the APEX user, but the idea is that this is more of a silent alarm meant to catch people who are not aware of this policy, or at least not aware of exactly what it’s looking for
  • It would be a good idea to wrap the CHECK_FOOTPRINT function, making it difficult to see what it is looking for
  • Fine Grained Auditing requires Enterprise Edition (no SE or XE)
  • The FGA_NOTIFY procedure uses UTL_MAIL which means you need to set the initialization parameter SMTP_OUT_SERVER to the servername:port of your email server

ScreenCast Click here for the full-size version
Code

– Make sure you set the spfile parameter SMTP_OUT_SERVER to the
– name and port of your mail server: yourmailserver.com:25
– Grant execute on utl_mail to FGA;
– Grant execute on DBMS_FGA to FGA;
– Also make sure you change the “sender” and “recipients”
– parameters in the call to utl_mail

create or replace function check_footprint
return number
as
begin
    if (sys_context(’userenv’,’session_user’) = ‘APEX_PUBLIC_USER’
        AND
        sys_context(’userenv’,'module’) = ‘APEX:APPLICATION 106′)
        — Other thoughts:
        — Business Hours
        — (to_char(sysdate, ‘D’) between 2 and 6 and to_char(sysdate, ‘HH24′) between 8 and 18
    then
        return 1;
    else
        return 0;
    end if;
end check_footprint;
/

grant execute on check_footprint to public;

create or replace procedure fga_notify (
    schema1 in varchar2,
    table1  in varchar2,
    policy1 in varchar2)
as
    l_msg   varchar2(32767);

    function t_row(
        p_label     in varchar2,
        p_data      in varchar2)
    return varchar2
    is
    begin
        return ‘<tr><td style=”text-align:right;”>’||p_label||’</td>’||
    ‘    <td style=”font-weight:bold;”>’||p_data||’</td></tr>’||utl_tcp.crlf;
    end t_row;

begin
    l_msg := ‘<html><head><style type=”text/css”>body{font-family:helvetica}</style></head><body>’||
    ‘<table style=”boder:0px;”>’||
    t_row(’Schema’,schema1)||
    t_row(’Table’,table1)||
    t_row(’Policy’,policy1)||
    t_row(’User’,user)||
    t_row(’Client Info’,sys_context(’userenv’, ‘client_info’))||
    t_row(’Client Identifier’,sys_context(’userenv’, ‘client_identifier’))||
    t_row(’IP Address’,sys_context(’userenv’, ‘ip_address’))||
    t_row(’Auth Type’,sys_context(’userenv’, ‘authentication_type’))||
    t_row(’Session ID’,sys_context(’userenv’, ’sessionid’))||
    t_row(’DB Name’,sys_context(’userenv’, ‘db_name’))||
    t_row(’Host’,sys_context(’userenv’, ‘host’))||
    t_row(’OS User’,sys_context(’userenv’, ‘os_user’))||
    t_row(’External Name’,sys_context(’userenv’, ‘external_name’))||
    t_row(’Current SQL’,'<pre> ‘||sys_context(’userenv’, ‘current_sql’)||’</pre>’)||
    ‘</table></body></html>’;

    utl_mail.send(
        SENDER      => ‘orcl_db@demo1′,
        RECIPIENTS  => ‘oracle@localhost’,
        –CC          => ”,
        –BCC         => ”,
        SUBJECT     => ‘Policy Violation’,
        MESSAGE     => l_msg,
        MIME_TYPE   => ‘text/html’,
        PRIORITY    => 1);
end fga_notify;
/
show errors
set termout off
BEGIN
DBMS_FGA.DROP_POLICY
(object_schema       => ‘FGA’,
     object_name         => ‘EMP’,
     policy_name         => ‘CHECK_FOOTPRINT);
END;
/
set termout on
BEGIN
DBMS_FGA.add_policy
   (object_schema       => ‘FGA’,
    object_name         => ‘EMP’,
    policy_name         => ‘ONLY_APEX_APP’,
    audit_condition     => ‘FGA.CHECK_FOOTPRINT = 0′,
    audit_column        => null,
    handler_schema      => ‘FGA’,
    handler_module      => ‘FGA_NOTIFY’,
    statement_types     => ‘INSERT,UPDATE,DELETE,SELECT’,
    ENABLE              => TRUE);
END;
/
– Audit entries are stored in sys.dba_fga_audit_trail

Posted in APEX, Oracle, Security | 4 Comments »