18. September 2012

Protect important roles with a password

Einführung

Wenn ich die Sicherheit einer Datenbank überprüfe, empfehle ich oft wichtige Rollen wie EXP_FULL_DATABASE mit einem Kennwort zu schützen.

Diesen Schutz einzuschalten, ist ganz einfach. Siehe folgendes Kommando.


alter role EXP_FULL_DATABASE identified by oracle;

Nun hat mich ein Kunde neulich gefragt: "Wie aktiviere ich die Rolle, wenn ich das Export-Utility (exp oder expdp) nutze?"

Das war eine sehr gute Frage. Natürlich können die Utilities keine password-geschützte Rollen automatisch setzen und ein erneutes Password abfragen. Entweder sind die notwendigen Rollen beim Login an das Utility gesetzt oder nicht. Das Setzen von Rollen mit Password macht man mit dem SET ROLE Kommando, also:


SET ROLE exp_full_database identified by oracle;
oder PL/SQL


begin DBMS_SESSION.SET_ROLE('EXP_FULL_DATABASE identified by oracle');end;/

Erst dann, wenn man das richtige Password wusste, erscheint die Rolle als gesetzt in der View SESSION_ROLES.
So, was nun?

Data Pump API nutzen

ok mit den Utilities geht das nicht, also die Data Pump API nutzen. Hier kann man leicht einen SQL Script bauen und im Script das Kennwort für das setzen der Rolle abfragen.



DECLARE  ind NUMBER;              -- Loop index  h1 NUMBER;               -- Data Pump job handle  percent_done NUMBER;     -- Percentage of job completeBEGIN-- set the EXP_FULL_DATABASE role  dbms_output.put_line('First set the password');  DBMS_SESSION.SET_ROLE('EXP_FULL_DATABASE identified by &role_password ');  dbms_output.put_line('...password set');-- Create a (user-named) Data Pump job to do a schema export.  dbms_output.put_line('Open Full Database Export');  h1 := DBMS_DATAPUMP.OPEN('EXPORT','FULL',NULL,'FULL_DB_EXPORT1','LATEST');  dbms_output.put_line('...export opened');-- Specify a single dump file for the job (using the handle just returned)-- and a directory object, which must already be defined and accessible-- to the user running this procedure.  DBMS_DATAPUMP.ADD_FILE(h1,'fulldb_export1.dmp','DATA_PUMP_DIR');-- Start the job. An exception will be generated if something is not set up-- properly.   DBMS_DATAPUMP.START_JOB(h1);-- Indicate that the job finished and detach from it.      dbms_output.put_line('Job has completed');  dbms_datapump.detach(h1);END;/exit;
Will man nun das Script als Export-Utility benutzen, würde die Ausführung wie nachfolgend dargestellt, stattfinden:


$ sqlplus scott/tiger @export_fulldatabase.sql
Vereinfacht dargestellt, könnte das eine Möglichkeit sein mit PASSWORD geschützten Rollen umzugehen.

Warum das alles?

Es gibt tatsächlich Datenbank Instancen in denen viele Endbenutzer Rollen Grants haben, die diese nicht benötigen. So kann es vorkommen, dass hunderte von Endbenutzern eine komplette DB exportieren können. Um die Logik der Anwendung nicht zu gefährden, empfiehlt es sich diese wichtige Rollen mit einem Password zu schützen.
Prinzipiell sollte man sich immer über die Zustände und Gefährdungen seines SYSTEMS im Klaren sein. Hierzu gehört auch gefährliche und hochprivilegierte Rollen zu kennen, und diese in einem gefährlichen Umfeld zu schützen.

Zusatz-Information:

Oracle empfiehlt anstelle der Kennwort-geschützten Rollen die Secure Application Roles stattdessen zu verwenden. Die Logik, die erforderlich ist, um eine Rolle automatisch zu setzen, wird in PL/SQL implementiert.
In der nachfolgenden Grafik werden beide Verfahren gegenüber gestellt.


Secure Application und password-geschützte Roles
 

23. August 2012

Keine DB Links in meiner Datenbank!

Einführung

Über das sichere Setup eines DB Links in einer Oracle Datenbank habe ich bereits schon berichtet. Neulich kam die Anfrage, wie man prinizipiell die Kommunikation über DB Links zwischen Datenbanken verhindern könnte.
Hierzu eine wirklich einfache Maßnahme, die man schnell umsetzen kann.

INIT.ORA Parameter OPEN_LINKS

Seit einigen Versionen kennt die Oracle Datenbank den init.ora Parameter OPEN_LINKS. Mit diesem Parameter stellt man ein, wie viele DB Links in einer Session geöffnet werden können. Der Default Wert ist 4. D.h. aus einer Datenbank Session heraus dürfen maximal 4 parallele Connections zu entfernten DBs aufgemacht werden. Das schöne bei diesem Parameter ist, dass hier auch external Procedures Calls von betroffen sind.

Will man nun in seiner gesamten DB Landschaft die Kommunikation mittels DB Links verhindern, so wäre eine einfache Maßnahme diesen Parameter in allen Datenbanken auf "0 (NULL)" zu setzen.

Also den Parameter ändern und Datenbank restarten und schon ist die Kommunikation nicht mehr möglich:

SQL > alter system set open_links=0 scope=spfile;
SQL > shutdown immediate
SQL > Startup

15. August 2012

Oracle Patch CVE-2012-3132: Privilege escalation

Oracle hat einen Patch zu einer Schwachstelle in der Datenbank geliefert. Genaueres kann man bei Heise lesen.

Nun, wie kann man schnell prüfen, ob die eigene Datenbank betroffen ist. Hierfür habe ich einen kleinen SQL-Script vorbereitet, der überprüft, ob die Privilegien, die erforderlich sind diese Schwachstelle zu nutzen, in der Datenbank vergeben wurden.

DB-User, die folgende Privilegien besitzen, könnten die Schwachstelle ausnutzen und somit  hochprivilegierte Rechte erlangen:
  • CREATE TABLE
  • CREATE PROCEDURE
  • EXECUTE ON CTX_DDL
  • EXECUTE ON DBMS_STAT
Folgendes Script könnt Ihr ausführen, um dies schnell zu prüfen:
set heading off
set scan off
select '********** DB SECURITY CHECK USERRIGHTS'||sysdate||
       ' FOR DATABASE: '||name||' **********' from v$database;
set heading on;
echo off; 
feedback off;
verify off; 
underline on;
timing off;
set linesize 400
set pages 1000

spool output.log
col owner format a30
col table_name format a30
col privilege format a30
col grantee format a30
SELECT * from (
select NULL OWNER, 'SYSTEM PRIV' TABLE_NAME, 
       privilege, grantee from dba_sys_privs
 where privilege in ('CREATE TABLE',
                     'CREATE PROCEDURE', 
                     'CREATE ANY TABLE',
                     'CREATE ANY PROCEDURE')
UNION
select owner,
       table_name,
       privilege,
       grantee
  from dba_tab_privs
where  privilege = 'EXECUTE' 
  and table_name in ('DBMS_STATS', 
                     'CTX_DDL')
)
order by grantee, privilege;
col owner clear
col table_name clear
col privilege clear
col grantee clear
spool off
exit

In meiner Datenbank ist genau ein Benutzer betroffen und zwar SCOTT. Die output.log Datei zeigt das Ergebnis.
Der nächste Schritt: Überprüfen, ob die Privilegien notwendig sind, wenn nein entziehen. Danach Patch einspielen.
Oracle Details finden Ihr hier.

13. August 2012

Oracle: Change to Audit by Session

Die Empfehlung lautet, Oracle Auditing Statements mittels AUDIT BY ACCESS einzustellen.
In der Dokumentation findet Ihr eine Zusammenfassung:

Ich habe das mal ausprobiert

Fangen wir mit dem by Session Audit an. Ich möchte gerne ein SELECT meines DB Accounts AUDITSESSION auf eine Tabelle TEST protokollieren. Wenn ich mit dem DB Account AUDITSESSION in der Datenbank eine Abfrage gegen die Tabelle TEST ausführe, so wird das protokolliert:
SQL > connect auditsession
SQL > select  * from test;

Die Protokollierung zeigt mir einen AUDIT_ACTION_CODE (103)= SESSION REC an, sowie den vorherigen Login.

Nun kommt by Access Audit an die Reihe. Ich wiederhole das SELECT meines DB Accounts AUDITSESSION auf die Tabelle Test:
SQL > connect auditsession
SQL > select  * from test;
Die Ausgabe sieht fast identisch aus. Mit BY ACCESS wird aber der Action Code anders gewählt. Nun haben wir einen Action_Code 3 = SELECT.

FAZIT:
Oracle sagt in der Doku, dass mit BY ACCESS die Audit Informationen genauer sind. Ich habe nicht alle Spalten miteinander verglichen, aber dieses Beispiel zeigt einen Unterschied. Also immer BY ACCESS nutzen.

18. Juni 2012

Zugriffskontrolle auf Daten auch außerhalb der Datenbank

Was ist eigentlich, wenn die Daten die Datenbank verlassen?

Die Frage ist ganz einfach zu beantworten: "Dann verlassen sie den Zugriffskontrollschutz der Datenbank." D.h. im Klartext sie haben es nicht mehr unter Kontrolle war mit ihren Daten passiert.

Ein simples Beispiel: Es kommt sehr häufig vor, dass Daten aus der Datenbank exportiert werden. Hier steht ein geeignetes Tool zur Verfügung, welches ein Export ermöglicht (expdp). Das Ziel einer exportierung ist entweder ein einfaches Schema Backup für ein späteres Recovery mittels dem Import-Tool (impdp) oder aber die exportierten Daten sollen in einer anderen Instanz importiert werden.

Wenn ich nun Daten exportieren möchte, gehe ich wie folgt vor (Hier Export des kompletten HR Schemata):
$ expdp hr/hr DIRECTORY=DDIR dumpfile=n.dmp
 Sind die Daten exportiert, so finde ich die erstellt Dump-Datei=n.dump im entsprechenden Verzeichnis (DDIR) und möchte den Inhalt dieser binären Datei lesen. Hierfür rufe ich den vi Editor auf.
$ vi n.dmp
 Wie man in der Grafik sehen kann, ich der Inhalt im Klartext lesbar. Es existiert kein Zugriffsschutz auf diese vielleicht sehr sensiblen Daten (in unseren Beispiel, finden sich die Gehälter der Mitarbeiter).
Export-Dump unverschlüsselt
Fazit: Für jeden Export-Dump, der keine eingeschaltete Zugriffskontrolle besitzt, verliert man die Kontrolle über seine Daten.

Über diesen Fakt muss man sich bewußt sein. Es gibt verschiedene Möglichkeiten, sich diesem Risiko zu entledigen. Eine organisatorische Maßnahme wäre das Exportieren zu verbieten. Oder aber man verschlüsselt den Inhalt des Export-Dump und zwar mit Möglichkeiten, die die Datenbanken anbietet, um so eine vollständigen und transparenten Zugriffsschutz mit Datenbankmitteln weiter zu verfolgen.

Oracle bietet im Export-Tool verschiedene Möglichkeiten an, die Zugriffskontrolle auch in dem Dump-File zu aktivieren. Mit dem folgenden Aufruf erzielen Sie z.B. , dass die Daten in dem Dump-File automatisch verschlüsselt werden.
$ expdp hr/hr DIRECTORY=DDIR dumpfile=s.dmp encrypted_password=“verschluesselt”
$ vi n.dmp  
Schaue ich mir die generierte Datei mit einem Editor an, so kann ich keine Daten lesen.
 Verschlüsselter DUMP-File

Fazit:
Immer das Verlassen des datenbankbasierten Zugriffskontrollsystem beachten! Ab 11g lassen sich Export Dumps verschlüsseln.

Hinweis und Whitepaper zu diesem Thema:
http://download.oracle.com/otndocs/products/database/enterprise_edition/utilities/pdf/datapump11g_encrypted_1106.pdf

10. Mai 2012

Oracle and Kerberos (WebLogic)

Seit einigen Jahren sehe ich eine erhöhte Nachfrage, wie man existierende Benutzerverwaltungen auch für die Oracle-Welt nutzen möchte. Hier gibt es verschiedene Möglichkeiten, die man implementieren könnte.
Ein interessanter Weg ist die Nutzung der Windows AD Domäne als zentralen Service. In dieser Umgebung authentisieren sich Windows Clients über Kerberos an die AD Domäne. Nach einem erfolgreichen Login erhält der Client ein sogenannten Kerberos-Ticket. Dieses Ticket kann man weiterverwenden und so ein Single-Sign-on für andere Anwendungen erreichen, die Kerberos unterstützen.

Der nachfolgende Artikel beschreibt, wie man Kerberos mit dem Oracle Weblogic Server konfiguriert.

How To Configure Browser-based SSO with Kerberos/SPNEGO and Oracle WebLogic Server