Oracle – APEX Security (in den Zeiten der Cholera) Muniqsoft GmbH Tätigkeitsbereiche: Oracle IT-Consulting & Services und Software-Lösungen Oracle Support Hotline: Mo-Fr 8.00 – 18.00 Uhr Erweiterung um Rufbereitschaft auch am Wochenende möglich Oracle Schulungen (SQL, PL/SQL, DBA, APEX, … - verschiedene Schulungen, gerne auch Inhouse ) Demnächst: Oracle Online Schulungen in DEUTSCH Oracle Lizenzen Muniqsoft GmbH Schulungszentrum Grünwalder Weg 13a 82008 Unterhaching Tel.: 089 / 679090 40 Muniqsoft GmbH IT-Consulting & Support Witneystr. 1 82008 Unterhaching Tel.: 089 / 6228 6789 0 DOAG Agenda 1. Verschlüsselung von Daten und Item-Werten 2. Schutz vor SQL Injection 3. Authorisierungsfunktionen DOAG Agenda 1. Verschlüsselung von Daten und Item-Werten DOAG Session State Protection: Einstellungen Unrestricted: Item kann über URL manipuliert werden. Prüfsummen sind nicht notwendig. Restricted: Darf nicht via URL oder Postdata geändert werden. Checksum Required | Application Level: Auch andere Benutzer in der gleichen Applikation können die Prüfsumme erzeugen. Checksum Required | User Level: Nur Anwender, die in verschiedenen Sessions mit dem gleichen Benutzernamen arbeiten, können Prüfsumme erzeugen. Checksum Required | Session Level: Prüfsumme kann nur innerhalb der gleichen Session erzeugt werden. DOAG Prüfsummen wenn normalerweise eine Seite aufgerufen wird durch: f?p=110:2:2931570151131669:10:NO::: wird nach der Session State Protection folgende URL benutzt: f?p=110:2:2931570151131669:10:NO::: &cs=34470BDC193A3BAEDC1A5D109DF6230F5 eine Manipulation der URL wird dann quittiert mittels: Error The checksum computed on the request, clear cache, argument names, and argument values (11 [D22917669D08B70EBE16FCCB1F1B1FD0] ) did not match the checksum passed into the show procedure (4470BDC193A3BAEDC1A5D109DF6230F5). DOAG Itemwerte selbst verschlüsseln CREATE OR REPLACE FUNCTION crypt ( text IN VARCHAR2, key IN VARCHAR2 DEFAULT 'MuniQSoft_Key', cryptmode IN VARCHAR2 DEFAULT 'E') RETURN VARCHAR2 IS p_typ PLS_INTEGER:=4360; /* ENCRYPT_AES256+chain_cbc+ pad_pkcs5*/ BEGIN IF substr(upper(cryptmode),1,1)='E' THEN -- Verschlüsselung RETURN (sys.dbms_crypto.encrypt( src => sys.utl_i18n.string_to_raw(text,'AL32UTF8'), typ => p_typ, key => sys.utl_raw.cast_to_raw(key))); ELSE -- Entschlüsselung RETURN sys.utl_i18n.raw_to_char(sys.dbms_crypto.decrypt( src => text, typ => p_typ, key => sys.utl_raw.cast_to_raw(key))); END IF; END; / DOAG Verschlüsselte Itemwerte :P1_EMPNO:=RETURN crypt( :P1_EMPNO_ENC,'D'); SELECT crypt(empno) as empno FROM emp; Report Spalte (encrypted) App Item oder Hidden Item DOAG Decryption in Standard Item Beispiel: Hidden-Elemente verschlüsseln Hidden & Protected Item (P1_CRYPT_HD) anlegen Computation (Before Header) anlegen Typ: PL/SQL Function Body Inhalt: RETURN crypt('Hallo Welt',lpad('MuniQSoFt',32,'+#;')); Im HTML Quellcode findet man dann nur noch den folgenden Eintrag: <input type="hidden" name="p_t01" id="P1_CRYPT_HD" value="D6436A70F09C5E52D717139E3C069FA1"> Alternativ kann auch ein Application Item verwendet werden DOAG Report=>Formular ID Verschlüsselung 1. Im Report die ID in der Query verschlüsseln: select crypt(empno,lpad('MuniQSoFt',32,'+#;')) as empno, ename,sal,deptno FROM emp; 2. Auf der Formularseite den Fetch Row Process auf Before Header mit Sequence Nr. 10 legen 3. Before Header Process (Seq: 5) anlegen: :P3_EMPNO:=crypt(:P3_EMPNO,' lpad('MuniQSoFt',32,'+#;'),'D'); DOAG Report=>Formular ID Verschlüsselung 3. Before Header Process (Seq: 20) anlegen (damit der Wert auf der Seite auch verschlüsselt angezeigt wird): :P3_EMPNO:=crypt(:P3_EMPNO, lpad('MuniQSoFt',32,'+#;')); 4. After Submit Process anlegen (Seq:1), der den Wert ggf. für Update/Delete entschlüsselt :P3_EMPNO:=crypt(:P3_ID, lpad('MuniQSoFt',32,'+#;'),'D'); DOAG Gefälschte Formularwerte mittels Firebug können Item-Werte direkt in der Webseite manipuliert werden auch durch eingeschaltete Prüfsummen kann dies nicht verhindert werden (nur bei der Weiterverabeitung bekommt man dann einen Fehler) Workaround: Verwenden Sie einen After Submit Prozess, der die ausgewählten Werte nochmals prüft So darf z.B. der Rückgabewert nicht 1000 lauten wenn nur 10 und 20 in einer Select-List zur Verfügung standen DOAG Gefälschte Formularwerte (Vorsicht) Sowohl Validation als auch der After Submit Process (mit RAISE_APPLICATION_ERROR) brechen zwar die weitere Verarbeitung der Seite ab, laden aber die aktuelle Seite mit dem gefälschten Wert erneut !!! Lösung: After Submit Process Prüfung, ob Wert des Items ok, wenn nicht: apex_authentication.logout( p_app_id=>:APP_ID,p_session_id=>0); DOAG Gefälschte Formularwerte: Lösung Legen Sie eine Select Liste an (MD5 kann auch durch andere Routine ersetzt werden!) Source: SELECT distinct job, job||':'||wwv_flow_item.md5(job) r FROM emp Oder SELECT distinct job, job:'||sys.dbms_crypto.hash( sys.utl_raw.cast_to_raw(job), 4 /*sh1*/) r FROM emp; DOAG Gefälschte Formularwerte: Lösung Als Validation: Function Returning Boolean: IF wwv_flow_item.md5( substr(:P29_JOB_SEC,1,instr(:P29_JOB_SEC,':')-1))= substr(:P29_JOB_SEC,instr(:P29_JOB_SEC,':')+1) then RETURN true; -- Prüfsumme passt zu Wert ELSE RETURN false; -- Prüfsumme passt nicht zu Wert END IF; DOAG Länge der Eingabefelder Sie können die Textbox-Länge begrenzen (z.B. auf 20 Zeichen) Ein Hacker könnte jedoch mittels Firebug die Länge wieder erhöhen Mit einer Validation wird nun einfach geprüft, ob die Textlänge länger als angegeben ist Validation auf NOT Exists setzen mit SELECT 1 FROM APEX_050000.APEX_APPLICATION_PAGE_ITEMS WHERE application_id=:APP_ID AND item_name='P3_ENAME' AND length(:P3_ENAME)>item_element_max_length DOAG Automatische Prüfung der Feldlänge Legen Sie einen Applikation Prozess an: DECLARE stmt VARCHAR2(32000); BEGIN FOR c IN (SELECT PAGE_ID,PAGE_NAME,ITEM_NAME, ITEM_ELEMENT_WIDTH,ITEM_ELEMENT_MAX_LENGTH FROM APEX_050000.APEX_APPLICATION_PAGE_ITEMS WHERE application_id=:APP_ID AND page_id=:APP_PAGE_ID AND ITEM_ELEMENT_MAX_LENGTH IS NOT NULL) LOOP stmt:='BEGIN IF length(v('''||c.item_name||''')) > '||c.ITEM_ELEMENT_MAX_LENGTH||q'! THEN RAISE_APPLICATION_ERROR(-20500,'Hacker attack detected'); END IF; END; !'; EXECUTE IMMEDIATE stmt; END LOOP; END; DOAG Appliction Items Vorteil: erscheint auf keiner HTML Seite im Quellcode und kann damit weder gelesen noch geändert werden DOAG Agenda 2. SQL Injektion DOAG SQL Injection Einleitung SQL Injection ist der Versuch zusätzliche Kommandos/Filter in ein SQL Befehl einzubauen Was geht bei Oracle nicht: Mit Semikolon ein weiteres Kommando anhängen: SELECT sal FROM emp WHERE empmno=7839; delete from emp; Welche Angriffsmöglichkeiten hat der Hacker? Hinzufügen von Filtern: OR 1=1 (komplette Tabelle anzeigen) Einbauen von SQL Funktionen, die als autonome Transaktionen in der DB Änderungen durchführt DOAG Was ist möglich mit SQL Injection Herausbekommen, welche Benutzer installiert sind: select * from dual where 1=sys.dbms_metadata.openw(null, (select listagg(username, ':') within group (order by username) from all_users)) Textlänge: 113! ORA-31600: Ungültiger Eingabewert ANONYMOUS:APEX_050000:APEX_PUBLIC_USER:APPQOSSYS:AUDSYS:BI :CTXSYS:DBSFWUSER:DBSNMP:DIP:DVF:DVSYS:FLOWS_FILES:GGSYS:G SMADMIN_INTERNAL:GSMCATUSER:GSMUSER:HR:IX:LBACSYS:MDDATA:M DSYS:OE:OJVMSYS:OLAPSYS:ORACLE_OCM:ORDDATA:ORDPLUGINS:ORDS YS:OUTLN:PM:REMOTE_SCHEDULER_AGENT:SCOTT:SH:SI_INFORMTN_SC HEMA:SPATIAL_CSW_ADMIN_USR:SPATIAL_WFS_ADMIN_USR:SYS:SYS$U MF:SYSBACKUP:SYSDG:SYSKM:SYSRAC:SYSTEM:WMSYS:XDB:XS$NULL für Parameter VERSION in Funktion OPENW ORA-06512: in "SYS.DBMS_SYS_ERROR", Zeile 105 DOAG SQL Injection APEX ist bei falscher Anwendung für SQL Injection Angriffe nutzbar! Beispiel: SELECT * FROM scott.emp WHERE ename='&P1_ENAME.'; Nun setzt der Benutzer in der Textbox P1_EMPNO folgenden Text ein: A' OR 'a'='a => Filter lautet dann: WHERE ename='A' OR 'a'='a' Dies hat zur Folge, dass alle Zeilen der Tabelle angezeigt werden DOAG SQL Injection Verwenden Sie besser Bindvariablen als Filtervariablen Beispiel: SELECT * FROM scott.emp WHERE ename=:P1_ENAME Bindvariablen dürfen nur im Filter der Select Anweisung verwendet werden, keinesfalls bei Spalten oder Tabellennamen Wenn möglich, sollte die Session State Security Function von Apex verwendet werden Auch VPD (Virtual Private Database) (nur in EE verfügbar) sollte, wenn möglich, eingesetzt werden Ab Version 12c können auch die neuen RAS Funktionen verwendet werden DOAG SQL Injection Weitere Möglichkeiten einen SQL-Befehl zu infiltrieren: UNION Klausel an bestehenden SQL-Befehl anhängen SELECT * FROM emp UNION SELECT … FROM all_tables; Sub SELECT anhängen Aufruf von gefährlichen Packages/Funktionen WHERE Klausel auskommentieren --WHERE DOAG SQL Injection Tipps & Tricks Müssen Textersetzungsvariablen benutzt werden (z.B. für einen Tabellennamen), verwenden Sie folgende Syntax: (" wird aus String entfernt und Spalten und Objektnamen werden in der Form "Obj-Name" benutzt) declare s varchar2(32767); begin s := 'select '|| '"'||replace(:P1_COL,'"','')||'" '; s := s||'from "'||replace(:P1_TABLE,'"','')||'"'; s := s||'where deptno = :P1_DEPTNO'; return s; end; DOAG Gefährliche Module für SQL Injection Schlecht: Besser: APEX Textersetzungsvariablen (&MY_VAR.) Bindvariablen in APEX (:MY_VAR) EXECUTE IMMEDIATE PL/SQL Cursor Dynamische Cursor CURSOR LOOP OPEN FETCH CLOSE REF Cursor Dbms_sql In den anderen Hochsprachen: Feldlängen begrenzen Filter einbauen Werte maskieren DOAG Verhindern der With Klausel Ab Version 12c kann ohne ein CREATE PROCEDURE Recht eine Prozedur/Funktion in die WITH Klausel gepackt werden. Sie können das durch umschließen des Statements verhindern, mittels: SELECT * FROM ( <dyn SQL Statement>); Wurde hier eine With Klausel verwendet, stürzt der SQL Befehl ab mit: ORA-00933: SQL-Befehl wurde nicht korrekt beendet DOAG Ausführungsplan gegen SQL Injection Wollen Sie nur sicherstellen, ob keine fremden Tabellen oder Views verwendet worden sind, können Sie in einem Prozess einen EXPLAIN PLAN durchführen Dieser ermittelt die beteiligten Objekte für den Ausführungsplan. Erscheinen dort zu viele oder falsche Objekte, hat eine SQL Injection stattgefunden Leider lassen sich damit keine Funktionsaufrufe überprüfen DOAG SQL Injection: Lösungen Filtern Sie die Benutzereingabe mittels des Package dbms_assert Prüfung auf nutzbare SQL-Objektnamen: SELECT DBMS_ASSERT.simple_sql_name('007Bond') FROM dual; SQL Error: ORA-44003: Ungültiger SQL-Name ORA-06512: in "SYS.DBMS_ASSERT", Zeile 146 Prüfung auf nutzbares Schema, Objekt und Linknamen: SELECT DBMS_ASSERT.qualified_sql_name ('schema.object@http:\\www.ard.de') as check_input FROM dual; SQL Error: ORA-44003: Ungültiger SQL-Name ORA-06512: in "SYS.DBMS_ASSERT", Zeile 146 DOAG SQL Injection: Lösungen Prüfung auf existierende Schemata Hinweis: Groß- und Kleinschreibung ist bedeutend SELECT dbms_assert.schema_name('sys') FROM dual; ERROR at line 1: ORA-44001: invalid schema ORA06512: at "SYS.DBMS_ASSERT", line 243 Prüfung auf existierendes Objekt SELECT DBMS_ASSERT.sql_object_name('hack') FROM dual; ERROR at line 1: ORA-44002: invalid object name ORA06512: at "SYS.DBMS_ASSERT", line 283 DOAG SQL Injection: Lösungen Ausgabe in Doppelhochkommata setzen und in Großbuchstaben wandeln SELECT DBMS_ASSERT.enquote_name('mein hund ist blau') FROM dual; "MEIN HUND IST BLAU" SELECT DBMS_ASSERT.enquote_name('mein hund ist "blau"') FROM dual; SQL Error: ORA-06502: PL/SQL: numerischer oder Wertefehler ORA-06512: in "SYS.DBMS_ASSERT", Zeile 314 ORA-06512: in "SYS.DBMS_ASSERT", Zeile 343 DOAG SQL Injection: Lösungen Prüfung, ob einfache Hochkommata falsch verwendet werden SELECT DBMS_ASSERT.enquote_literal('Ich bin ''wichtig'' ') FROM dual; Error report: SQL Error: ORA-06502: PL/SQL: numerischer oder Wertefehler ORA-06512: in "SYS.DBMS_ASSERT", Zeile 314 ORA-06512: in "SYS.DBMS_ASSERT", Zeile 358 DOAG SQL Injection und reguläre Ausdrücke Lösung mittels regulärer Ausdrücke SELECT regexp_replace( 'Hallo ''x'' ','[^[:alnum:][:blank:]]','') FROM dual; =>Hallo x SELECT regexp_replace( 'Hallo "x" ','[^[:alnum:][:blank:]]','') FROM dual; =>Hallo x Anmerkung: Weitere Sonderzeichen müssen nach Bedarf freigegeben werden, wie z.B. - ; : . DOAG Eingabe des Benutzers maskieren Textbox: P1_SUCHE FILTER lautet dann s:=s||' AND ename='||chr(39)|| replace(:P1_SUCHE,chr(39),chr(39)||chr(39)) ||chr(39); RETURN s; Damit wird dann z.B. aus P1_SUCHE: Normale Eingabe: KING wird zu 'KING' Hacker Eingabe: a' OR 1=1 wird zu 'a'' OR 1=1' und ist damit ungültig DOAG Agenda 3. Authorisierungsfunktion DOAG Benutzergruppen Sie können mehrere Benutzer in eine Gruppe legen (unter Home / Adminis./ Manage Users/Groups) Klicken Sie auf Groups und legen Sie eine neue Gruppe an Klicken Sie nun auf den Benutzer Bei "User Groups" lässt sich nun die Gruppe einstellen DOAG Benutzergruppen Legen Sie eine neue Security Policy an (wie zuvor beschrieben) RETURN wwv_flow_user_api. current_user_in_group( 'ADMIN') gibt dann True/False zurück DOAG Benutzerauthentifizierung Gehen Sie auf Shared Components/Authentication Schemas Zur Wahl stehen folgende Methoden: Application Express (Benutzerverwaltung durch APEX) Database (via DAD) Database Accounts (Accounts der DB) DOAG Eigene Authentifizierung der Benutzer Man kann sich eine eigene Anmeldeprozedur schreiben. Legen Sie dazu eine neue Authentifizierung (Shared Components/Authentification Schemes) an Im Bereich Login Processing wird dann der Name der Funktion in ein RETURN Statement eingebettet (Hier: RETURN check_user;) DOAG Eigene Authentifizierung der Benutzer Eine benutzerdefinierte Function (check_user) muss folgende Übergabeparameter besitzen: p_username und p_password Returntyp: Boolean (True= Benutzer authentifiziert) DOAG Muniqsoft GmbH Tätigkeitsbereiche: Oracle IT-Consulting & Services und Software-Lösungen Oracle Support Hotline: Mo-Fr 8.00 – 18.00 Uhr Erweiterung um Rufbereitschaft auch am Wochenende möglich Oracle Schulungen (SQL, PL/SQL, DBA, APEX, … - verschiedene Schulungen, gerne auch Inhouse ) Oracle Online Schulungen in DEUTSCH Oracle Lizenzen Muniqsoft GmbH IT-Consulting & Support Witneystr. 1 82008 Unterhaching Tel.: 089 / 6228 6789 0 Muniqsoft GmbH Schulungszentrum Grünwalder Weg 13a 82008 Unterhaching Tel.: 089 / 679090 40 DOAG