Bonjour à toutes et tous et bonne année 2024 !
Nous débutons cette nouvelle année avec un article, une fois de plus, en lien avec la sécurité ! C’est un sujet que nous avons grandement abordé au cours de l’année 2023, sur les SGBD SQL Server et PostgreSQL.
Pour débuter 2024 dans la même voie, je vous propose une présentation de la brique SQL Firewall présente dans la version Oracle 23c.
Pour qualifier et tester les nouveautés Oracle 23c, nous avons la possibilité de télécharger et installer l’édition FREE Edition qui, de plus, est utilisable “on prem”.
Ce tableau, fourni par Oracle, nous montre les différentes offres présentes :
Vous remarquerez qu’il n’y a, à ce jour, ni Standard Edition 2, ni offre Enterprise Edition on prem.
Une note Oracle indique cependant une éventuelle prise en charge de cette version dès le premier semestre 2024 sous Linux x86-64
Release Schedule of Current Database Releases (Doc ID 742060.1)
Nous suivrons plus précisément les informations à ce sujet au cour de ce début d’année.
Installation Oracle 23c FREE Edition
Nous disposons d’une VM EC2 de type Rocky Linux 8.6 pour tester la nouvelle version Oracle 23c
[oracle@ etc]$ cat os-release NAME="Rocky Linux" VERSION="8.6 (Green Obsidian)" ID="rocky" ID_LIKE="rhel centos fedora" VERSION_ID="8.6" PLATFORM_ID="platform:el8" PRETTY_NAME="Rocky Linux 8.6 (Green Obsidian)" ANSI_COLOR="0;32" CPE_NAME="cpe:/o:rocky:rocky:8:GA" HOME_URL="https://rockylinux.org/" BUG_REPORT_URL="https://bugs.rockylinux.org/" ROCKY_SUPPORT_PRODUCT="Rocky Linux" ROCKY_SUPPORT_PRODUCT_VERSION="8" REDHAT_SUPPORT_PRODUCT="Rocky Linux" REDHAT_SUPPORT_PRODUCT_VERSION="8"
L’installation de la version Oracle 23c Free Edition sur un fork Red Hat est on ne peut plus simple :
- Télécharger le package rpm de preinstallation -> oracle-database-preinstall-23c-1.0-1.el8.x86_64.rpm
- Télécharger le package rpm d’installation du moteur Oracle 23c -> oracle-database-free-23c-1.0-1.el8.x86_64.rpm
Une fois téléchargés et copiés vers le serveur linux, passer à l’installation via rpm sous “root“
— Le package de preinstallation permettant la configuration OS propre à Oracle.
[root@ ~]# rpm -iv /tmp/oracle-database-preinstall-23c-1.0-0.5.el8.x86_64.rpm warning: /tmp/oracle-database-preinstall-23c-1.0-0.5.el8.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID ad986da3: NOKEY Verifying packages... Preparing packages... oracle-database-preinstall-23c-1.0-0.5.el8.x86_64
— Puis le package d’installation du moteur Oracle 23c. Attention, l’installation va se faire dans un répertoire “/opt”. Prévoir une place d’au moins 8Go sur ce montage.
[root@ ~]# rpm -iv /tmp/oracle-database-free-23c-1.0-1.el8.x86_64.rpm warning: /tmp/oracle-database-free-23c-1.0-1.el8.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID ad986da3: NOKEY Verifying packages... Preparing packages... oracle-database-free-23c-1.0-1.x86_64 [INFO] Executing post installation scripts... [INFO] Oracle home installed successfully and ready to be configured. To configure Oracle Database Free, optionally modify the parameters in '/etc/sysconfig/oracle-free-23c.conf' and then run '/etc/init.d/oracle-free-23c configure' as root.
Valider l’installation des packages
[root@ ~]# rpm -qav | grep -i oracle oracle-database-preinstall-23c-1.0-0.5.el8.x86_64 oracle-database-free-23c-1.0-1.x86_64
[root@ ~]# ls /opt/oracle/product/23c/dbhomeFree/ addnode clone ctx deinstall env.ora instantclient jdk LICENSE nls OPatch ord plsql R root.sh slax sqlplus usm assistants crs cv demo has inventory jlib md odbc opmn oss precomp racg runInstaller sqlcl srvm utl bin crypto data diagnostics hs javavm ldap mgw olap oracore oui python rdbms schagent.conf sqlj ss_oracle.sdo.acl xdk cfgtoollogs css dbs dv install jdbc lib network oml4py oraInst.loc perl QOpatch relnotes sdk sqlpatch ucp
[root@ ~]# /opt/oracle/product/23c/dbhomeFree/root.sh Check /opt/oracle/product/23c/dbhomeFree/install/root_************_2023-12-20_11-38-30-060078626.log for the output of root script
— Comme indiqué en fin d’installation, lancer ‘/etc/init.d/oracle-free-23c configure’ sous “root” pour créer une nouvelle instance. Le script est interactif et vous serez amener à saisir certaines informations comme le mot de passe SYS/SYSTEM et PDB_ADMIN.
[root@~]# /etc/init.d/oracle-free-23c configure Specify a password to be used for database accounts. Oracle recommends that the password entered should be at least 8 characters in length, contain at least 1 uppercase character, 1 lower case character and 1 digit [0-9]. Note that the same password will be used for SYS, SYSTEM and PDBADMIN accounts: Confirm the password: Configuring Oracle Listener. Listener configuration succeeded. Configuring Oracle Database FREE. Enter SYS user password: ************ Enter SYSTEM user password: ************** Enter PDBADMIN User Password: ************ Prepare for db operation 7% complete Copying database files 29% complete Creating and starting Oracle instance 30% complete 33% complete 36% complete 39% complete [WARNING] ORA-20002: Directory creation failed ORA-06512: at "SYS.DBMS_QOPATCH", line 1644 ORA-06512: at "SYS.DBMS_QOPATCH", line 1521 ORA-06512: at line 1 43% complete Completing Database Creation 47% complete 49% complete 50% complete Creating Pluggable Databases 54% complete 71% complete Executing Post Configuration Actions 93% complete Running Custom Scripts 100% complete Database creation complete. For details check the logfiles at: /opt/oracle/cfgtoollogs/dbca/FREE. Database Information: Global Database Name:FREE System Identifier(SID):FREE Look at the log file "/opt/oracle/cfgtoollogs/dbca/FREE/FREE1.log" for further details. Database configuration failed. Check logs under '/opt/oracle/cfgtoollogs/dbca'.
Ne pas tenir compte de l’erreur lors de la création du DIRECTORY Oracle, celui ci pointe vers un répertoire inexistant sur la machine. Il nous sera possible d’en créer un ultérieurement.
Présentation SQL Firewall
Comme son nom l’indique , Oracle 23c SQL Firewall est un firewall applicatif qui, au delà d’un firewall web classique (WAF), est capable d’interpréter le code SQL en entrée directement en base.
Comme le montre l’image extraite de la documentation Oracle officielle, le processus passe par une phase d’apprentissage des différentes requêtes envoyées à la base de données.
Une liste des requêtes dites “autorisées” doit être générée afin de valider les opérations business officielles d’une production classique au cour de la journée.
Ceci peut bien évidemment être facilité par un éditeur qui connait parfaitement son application, et donc son modèle conceptuel de données et les requêtes SQL qui en découlent.
Une fois cette phase d’apprentissage établie, nous allons pouvoir valider les requêtes capturées et dresser la liste “verte” des requêtes autorisées.
C’est à partir de la que l’on pourra potentiellement, empêcher tout autre code SQL de passer en base.
Le filtrage peut se faire selon plusieurs contextes à savoir, un utilisateur en particulier, une adresse IP où bien un programme.
Les prérequis pour Oracle 23c SQL Firewall
Rappelons que depuis la version 21c, Oracle nous impose la gestion du multitenant avec la possibilité de créer 3 PDBs gratuitement.
L’instance FREE comporte donc bien une PDB exploitable en lecture/écriture
[oracle@ ~]$ . oraenv ORACLE_SID = [oracle] ? FREE The Oracle base has been set to /opt/oracle [oracle@ ~]$ sqlplus / as sysdba SQL*Plus: Release 23.0.0.0.0 - Production on Wed Dec 20 11:46:08 2023 Version 23.3.0.23.09 Copyright (c) 1982, 2023, Oracle. All rights reserved. Connected to: Oracle Database 23c Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free Version 23.3.0.23.09 SQL> show pdbs; CON_ID CON_NAME OPEN MODE RESTRICTED ---------- ------------------------------ ---------- ---------- 2 PDB$SEED READ ONLY NO 3 FREEPDB1 READ WRITE NO
Il sera donc nécessaire, pour se connecter à la PDB FREEPPDB1 depuis un compte applicatif, d’ajouter une entrée dans le tnsnames.
FREEPDB1 = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = ip-********.eu-west-3.compute.internal)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = FREEPDB1) ) )
Configuration des données.
Pour notre cas pratique, nous créons 3 utilisateurs Oracle dans la PDB. 1 utilisateur administrateur du Firewall, 1 utilisateur propriétaire des objets et 1 utilisateur applicatif utilisant des ordres DML sur les objets. A noter le rôle “sql_firewall_admin” pour le compte “FW_ADMIN”.
SQL> alter session set container = FREEPDB1; SQL> create user FW_ADMIN identified by passwdfwadmin; SQL> grant create session, sql_firewall_admin, audit_admin to FW_ADMIN; SQL> create user application_owner identified by passwdappliowner default tablespace USERS quota unlimited on USERS; SQL> grant create session, create table, create view, create procedure, create synonym to application_owner; SQL> create user application identified by passwdappli default tablespace USERS quota unlimited on USERS; SQL> grant create session to application; SQL> grant select any table on schema application_owner to application;
Création des objets et du jeu de données
SQL> create table salaries ( id number(15), name VARCHAR2(128), address VARCHAR2(400), date_entrée VARCHAR2(128)); SQL> create table entreprise (ent_id VARCHAR2(128), raison_sociale varchar2(20),taille_salaries number(5)); SQL> insert into salaries values (154484, 'Manuel', '14 rue voltaire', '16/12/2020'); SQL> insert into salaries values (275558, 'Jack', '24 rue du départ', '12/10/2005'); SQL> insert into salaries values (285548, 'Cyril', '27 avenue Pasteur', '01/02/2006'); SQL> insert into salaries values (472245, 'Thomas', '12 avenue principale', '15/02/2021'); SQL> insert into entreprise values (12232,'SARL',1200); SQL> insert into entreprise values (13456,'SARL', 500); SQL> insert into entreprise values (22522,'SA',288); SQL> insert into entreprise values (25485,'SA', 144); SQL> insert into entreprise values (31411,'SA',524); SQL> insert into entreprise values (36879,'SARL', 56); SQL> insert into entreprise values (40125,'EURL', 120); SQL> insert into entreprise values (44588, 'SA', 2510); SQL> create or replace view application_owner.somme_salaries_sa as select raison_sociale, sum(taille_salaries) as "Somme_SA" from application_owner.entreprise where raison_sociale='SA' group by raison_sociale; SQL> create or replace procedure maj_salarie_addresse (id number, address varchar2) is req varchar2(1000); begin req := 'BEGIN UPDATE salaries SET address = ''' || address || ''' WHERE id = ''' || id || '''; COMMIT; END;'; DBMS_OUTPUT.PUT_LINE('Query: ' || req); execute immediate req; end; / SQL> CREATE OR REPLACE PROCEDURE maj_entreprise_salaries ( id number, taille_salaries number) IS req VARCHAR2(1000); BEGIN req := 'BEGIN UPDATE entreprise SET taille_salaries =''' || taille_salaries || ''' WHERE ent_id = ''' || id || '''; COMMIT; END;'; DBMS_OUTPUT.PUT_LINE('Query: ' || req); EXECUTE IMMEDIATE req; END; / SQL> grant execute on application_owner.maj_salarie_addresse to application; SQL> grant execute on application_owner.maj_entreprise_salaries to application; SQL> grant select on application_owner.somme_salaries_sa to application; SQL> grant insert, update, delete on application_owner.salaries to application; SQL> grant insert, update, delete on application_owner.entreprise to application; SQL> create public synonym somme_salaries_sa for application_owner.somme_salaries_sa; SQL> create public synonym maj_salarie_addresse for application_owner.maj_salarie_addresse; SQL> create public synonym maj_entreprise_salaries for application_owner.maj_entreprise_salaries;
Capture des requêtes dans Oracle 23c SQL Firewall
A cette étape, nous pouvons commencer à capturer de l’activité afin de débuter “l’apprentissage” pour le SQL Firewall.
Tout d’abord, il nous faut activer le Firewall et vérifier son statut avec le compte FW_ADMIN.
SQL> connect fw_admin@freepdb1 Enter password: Connected. SQL> exec dbms_sql_firewall.enable; PL/SQL procedure successfully completed. SQL> select STATUS,STATUS_UPDATED_ON from dba_sql_firewall_status; STATUS STATUS_UPDATED_ON -------- --------------------------------------------------------------------------- ENABLED 20-DEC-23 03.45.23.677823 PM +00:00
Démarrer la capture d’activité pour l’utilisateur Oracle nommé application.
SQL> exec dbms_sql_firewall.create_capture('APPLICATION');
Vérifier le statut de la capture
SQL> col LAST_STARTED_ON for a35 SQL> col LAST_STOPPED_ON for a35 SQL> select * from dba_sql_firewall_captures where username='APPLICATION'; USERNAME TOP_LEVEL_ONLY STATUS LAST_STARTED_ON LAST_STOPPED_ON --------------- -------------- -------- ----------------------------------- ----------------------------------- APPLICATION N ENABLED 20-DEC-23 03.49.48.573900 PM +00:00
La suite consiste donc à générer de l’activité avec le compte APPLICATION
SQL> conn application@FREEPDB1 Connected. SQL> execute maj_salarie_addresse(154484, '18 rue voltaire'); SQL> execute maj_entreprise_salaries(25485, 146); SQL> select name, address from application_owner.salaries where id = 472245; SQL> insert into application_owner.salaries values (510024, 'Marie', '12 rue de l eglise', '20/12/2023'); SQL> select name, address from application_owner.salaries where id = 510024; SQL> delete from application_owner.salaries where id = 510024; SQL> select name, address application_owner.salaries where id = 510024; SQL> select * from application_owner.somme_salaries_sa; SQL> select count(*) from application_owner.salaries where date_entrée > '01/01/2015';
Allons voir à présent ce que le Firewall a capturé comme requêtes. Stoppons la capture et allons lire dans les logs du Firewall
SQL> exec dbms_sql_firewall.stop_capture('APPLICATION'); PL/SQL procedure successfully completed. SQL> select username, ip_address, login_time, client_program, os_user from dba_sql_firewall_session_logs order by login_time; USERNAME IP_ADDRESS LOGIN_TIME CLIENT_PROGRAM OS_USER --------------- --------------- ----------------------------------- -------------------------------------------------- -------------------- APPLICATION 172.44.**** 20-DEC-23 04.08.38.884619 PM +00:00 sqlplus@ip-********.fr (TNS V1-V3) oracle APPLICATION 172.44.**** 20-DEC-23 04.15.26.633200 PM +00:00 sqlplus@ip-********.fr (TNS V1-V3) oracle APPLICATION 172.44.**** 20-DEC-23 04.19.46.220001 PM +00:00 sqlplus@ip-********.fr (TNS V1-V3) oracle
Nous avons capturé les différentes connexions avec le compte APPLICATION, grâce à cela, les informations sur les SQL lancés sont enregistrées.
A noter que les variables enregistrées sont “bindés”
SQL> select username, top_level, command_type, sql_text,sql_signature,accessed_objects from dba_sql_firewall_capture_logs where username = 'APPLICATION' order by command_type, sql_signature; USERNAME TOP_LEVEL COMMAND_TYPE --------------- --------- ---------------------------------------------------------------- SQL_TEXT -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- SQL_SIGNATURE ---------------------------------------------------------------- ACCESSED_OBJECTS -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- APPLICATION Y DELETE DELETE FROM APPLICATION_OWNER.SALARIES WHERE ID=:"SYS_B_0" 0D3C48AFA7C43F32036A1398B2C9FED8250C57D00C9731332E8B6BFAAD25F3A0 "APPLICATION_OWNER"."SALARIES" APPLICATION N EXECUTE BEGIN UPDATE ENTREPRISE SET TAILLE_SALARIES=? WHERE ENT_ID=?; COMMIT; END; 243A35B41DAB8171B60C30BE90A3D725DEEDA3A22C8E118B5EB7E99C8D73E890 "APPLICATION_OWNER"."ENTREPRISE" APPLICATION Y EXECUTE BEGIN MAJ_SALARIE_ADDRESSE (?,?); END; 6A8D28786FE3BFEBFEBEE70CF2AF81A3587F5FE8239696BE9939D443EFB52789 "APPLICATION_OWNER"."MAJ_SALARIE_ADDRESSE" APPLICATION N EXECUTE BEGIN UPDATE SALARIES SET ADDRESS=? WHERE ID=?; COMMIT; END; ED3DA8C122700A399BEB2D6C0CC88E5FC1B46A61961BF515E5DB0526856AD86A "APPLICATION_OWNER"."SALARIES" APPLICATION Y EXECUTE BEGIN MAJ_ENTREPRISE_SALARIES (?,?); END; F4F779482E86BC0537A6BC59470DB7E8A0EBBCF3B6F2CB21CE3242DC2863C45A "APPLICATION_OWNER"."MAJ_ENTREPRISE_SALARIES" APPLICATION Y INSERT INSERT INTO APPLICATION_OWNER.SALARIES VALUES (:"SYS_B_0",:"SYS_B_1",:"SYS_B_2",:"SYS_B_3") C24B251483E84751353F7B379414FFFBEBCC593E3E1CC32C0E419B69A66CA807 "APPLICATION_OWNER"."SALARIES" APPLICATION Y SELECT SELECT NAME,ADDRESS FROM APPLICATION_OWNER.SALARIES WHERE ID=:"SYS_B_0" 633C0FBB9B54CB5F6BC0A75B9BA34A2EA453671A78A799644CF4D7956F6EEE4B "APPLICATION_OWNER"."SALARIES" APPLICATION Y SELECT SELECT NAME,ADDRESS FROM APPLICATION_OWNER.SALARIES WHERE ID=:"SYS_B_0" 633C0FBB9B54CB5F6BC0A75B9BA34A2EA453671A78A799644CF4D7956F6EEE4B "APPLICATION_OWNER"."SALARIES" APPLICATION Y SELECT SELECT DECODE (USER,:"SYS_B_0",XS_SYS_CONTEXT (:"SYS_B_1",:"SYS_B_2"),USER) FROM SYS.DUAL 8CD0E5550A8AF32553BDED7C77B8CC1FD103C51F438E11F1BC5F9CA315102794 "SYS"."DUAL" APPLICATION Y SELECT SELECT DECODE (USER,:"SYS_B_0",XS_SYS_CONTEXT (:"SYS_B_1",:"SYS_B_2"),USER) FROM SYS.DUAL 8CD0E5550A8AF32553BDED7C77B8CC1FD103C51F438E11F1BC5F9CA315102794 "SYS"."DUAL" APPLICATION Y SELECT SELECT DECODE (USER,:"SYS_B_0",XS_SYS_CONTEXT (:"SYS_B_1",:"SYS_B_2"),USER) FROM SYS.DUAL 8CD0E5550A8AF32553BDED7C77B8CC1FD103C51F438E11F1BC5F9CA315102794 "SYS"."DUAL" APPLICATION Y SELECT SELECT * FROM APPLICATION_OWNER.SOMME_SALARIES_SA BCCB5D0F6B4DE96D7C9E52C8678C489698D4ED23F8FEEA120FFC701560C99D0C "APPLICATION_OWNER"."SOMME_SALARIES_SA" APPLICATION Y SELECT SELECT * FROM APPLICATION_OWNER.SOMME_SALARIES_SA BCCB5D0F6B4DE96D7C9E52C8678C489698D4ED23F8FEEA120FFC701560C99D0C "APPLICATION_OWNER"."SOMME_SALARIES_SA" APPLICATION Y SELECT SELECT COUNT (*) FROM APPLICATION_OWNER.SALARIES WHERE DATE_ENTR??E >:"SYS_B_0" EE000C28DC61F8D21DCDC9BB6880A315EB12CC3682E0D3CD47A01EACF915EF98 "APPLICATION_OWNER"."SALARIES" APPLICATION Y SELECT SELECT COUNT (*) FROM APPLICATION_OWNER.SALARIES WHERE DATE_ENTR??E >:"SYS_B_0" EE000C28DC61F8D21DCDC9BB6880A315EB12CC3682E0D3CD47A01EACF915EF98 "APPLICATION_OWNER"."SALARIES" APPLICATION N UPDATE UPDATE ENTREPRISE SET TAILLE_SALARIES=:"SYS_B_0" WHERE ENT_ID=:"SYS_B_1" 36FE5B2C529FD88D46DD6C69649D30C12719CD2600945F8EF2D4B3D039B4CD06 "APPLICATION_OWNER"."ENTREPRISE" APPLICATION N UPDATE UPDATE SALARIES SET ADDRESS=:"SYS_B_0" WHERE ID=:"SYS_B_1" 6D68C8BB02FFE46E37900E60275B0AB0698CF1217B95B3CA1C789E29FE8D0B6B "APPLICATION_OWNER"."SALARIES"
Chaque ordre SQL a une signature propre à lui. C’est ce qui permet au SQL Firewall de reconnaitre par la suite, tout ordre faisant parti de la liste.
Générer la liste “verte” de requêtes autorisées
La liste “verte” se crée avec le compte FW_ADMIN
SQL> connect fw_admin@FREEPDB1 Enter password: Connected. SQL> exec dbms_sql_firewall.generate_allow_list('APPLICATION'); PL/SQL procedure successfully completed. SQL>; col GENERATED_ON for a35 SQL> select USERNAME,GENERATED_ON,STATUS,STATUS_UPDATED_ON,TOP_LEVEL_ONLY from dba_sql_firewall_allow_lists where username='APPLICATION'; USERNAME GENERATED_ON STATUS STATUS_UPDATED_ON TOP_LEVEL_ONLY --------------- ----------------------------------- -------- ----------------------------------- -------------- APPLICATION 20-DEC-23 04.49.56.169700 PM +00:00 DISABLED 20-DEC-23 04.49.56.169700 PM +00:00 N
Pour le moment, le statut de la liste est à DISABLED car nous l’avons juste générée.
Comme évoqué quelques lignes au dessus, le contexte peut se faire via l’adresse IP
SQL> select * from sys.dba_sql_firewall_allowed_ip_addr where username='APPLICATION'; USERNAME IP_ADDRESS -------------------- ------------------------------ APPLICATION 172.44.*********
Le programme associé
SQL> select * from sys.dba_sql_firewall_allowed_os_prog where username='APPLICATION'; USERNAME OS_PROGRAM -------------------- -------------------------------------------------------------------------------------------------------------------------------- APPLICATION sqlplus@ip-172-44-*************s.fr (TNS V1-V3)
Ou bien le user OS
SQL> select * from sys.dba_sql_firewall_allowed_os_user where username='APPLICATION'; USERNAME OS_USER -------------------- -------------------------------------------------------------------------------------------------------------------------------- APPLICATION oracle
Activer la liste “verte”
la suite consiste à valider et surtout, activer cette liste. Ceci se fait avec le compte FW_ADMIN.
SQL> connect fw_admin@FREEPDB1 Enter password: Connected. SQL> exec dbms_sql_firewall.enable_allow_list('APPLICATION'); PL/SQL procedure successfully completed. SQL> select username, status, top_level_only, enforce, block from dba_sql_firewall_allow_lists where username='APPLICATION'; USERNAME STATUS TOP_LEVEL_ONLY ENFORCE BLOCK -------------------- -------------- -------------- --------------- -------------- APPLICATION ENABLED N ENFORCE_ALL N
Cette liste “verte” est donc activée, elle “trappe” les futures requêtes qui ne matcheraient pas avec celles qui sont enregistrées. Mais, le “BLOCK” est à N, donc l’utilisateur n’a pas de message d’erreur en cas de saisie d’une requête non reconnue.
Le user APPLICATION peut tout à fait faire un SELECT sur une table.
SQL> connect application@FREEPDB1 Enter password: Connected. SQL> select name from application_owner.salaries where id > 300000; NAME -------------------------------------------------------------------------------------------------------------------------------- Manuel Jack Cyril
Mais une fois connecté avec le user FW_ADMIN, une simple interrogation dans la vue DBA_SQL_FIREWALL_VIOLATIONS nous donne l’entrée suivante
SQL> select USERNAME,COMMAND_TYPE,SQL_TEXT,IP_ADDRESS,OS_USER,OCCURRED_AT from dba_sql_firewall_violations; USERNAME COMMAND_TYPE SQL_TEXT IP_ADDRESS OS_USER</pre> -------------------- --------------- -------------------------------------------------------------------------------- --------------- --------------- OCCURRED_AT --------------------------------------------------------------------------- APPLICATION SELECT SELECT NAME FROM APPLICATION_OWNER.SALARIES WHERE ID <:"SYS_B_0" 172.44.****** oracle 21-DEC-23 02.09.53.047973 PM +00:00
La requête lancée par le compte APPLICATION est donc bien enregistrée dans la liste des violations des règles du firewall.
Bloquer les requêtes non désirées
Le blocage de requêtes s’effecctue, avec le compte FW_ADMIN, en activant le mode BLOCK sur la liste “verte”
SQL> connect fw_admin@FREEPDB1 Enter password: Connected. SQL> exec dbms_sql_firewall.update_allow_list_enforcement('APPLICATION', block=>TRUE); PL/SQL procedure successfully completed.
Et lorsque nous souhaitons interroger la même requête avec le compte APPLICATION
SQL> connect application@FREEPDB1 Enter password: Connected. SQL> select name from application_owner.salaries where id > 300000; select name from application_owner.salaries where id > 300000 * ERROR at line 1: ORA-47605: SQL Firewall violation Help: https://docs.oracle.com/error-help/db/ora-47605/
Nous avons une belle erreur “ORA-47605” nous indiquant une violation des règles du Firewall. Petite nouveauté avec la 23c, Oracle nous donne l’URL pour rechercher directement la définition du message d’erreur.
Ceci se vérifie pour toute autre requête ne faisant pas partie de la liste “verte”
SQL> select * from application_owner.entreprise where taille_salaries > 10000; select * from application_owner.entreprise where taille_salaries > 10000 * ERROR at line 1: ORA-47605: SQL Firewall violation Help: https://docs.oracle.com/error-help/db/ora-47605/
Dans la vue DBA_SQL_FIREWALL_VIOLATIONS, ces 2 dernières requêtes nous sont relevées
SQL> connect fw_admin@FREEPDB1 Enter password: Connected. SQL> select USERNAME,COMMAND_TYPE,SQL_TEXT,OCCURRED_AT from dba_sql_firewall_violations; USERNAME COMMAND_TYPE SQL_TEXT -------------------- --------------- -------------------------------------------------------------------------------- OCCURRED_AT --------------------------------------------------------------------------- APPLICATION SELECT SELECT * FROM APPLICATION_OWNER.ENTREPRISE WHERE TAILLE_SALARIES >:"SYS_B_0" 21-DEC-23 02.30.31.690170 PM +00:00 APPLICATION SELECT SELECT NAME FROM APPLICATION_OWNER.SALARIES WHERE ID <:"SYS_B_0" 21-DEC-23 02.09.53.047973 PM +00:00 APPLICATION SELECT SELECT NAME FROM APPLICATION_OWNER.SALARIES WHERE ID <:"SYS_B_0" 21-DEC-23 02.24.29.523017 PM +00:00
Il est bien entendu possible de purger la table de log des requêtes interdites afin de réinitialiser son contenu.
SQL> exec dbms_sql_firewall.purge_log('APPLICATION', NULL, dbms_sql_firewall.VIOLATION_LOG); PL/SQL procedure successfully completed. SQL> select USERNAME,COMMAND_TYPE,SQL_TEXT,OCCURRED_AT from dba_sql_firewall_violations; no rows selected
Conclusion
Gardez à l’esprit que cette fonctionnalité SQL Firewall de Oracle peut vous protéger de toute injection SQL non désirée, mais ceci sous entend surtout que la phase “d’apprentissage” soit correctement maitrisée afin de ne pas se retrouver avec une application potentiellement bloquée par des ordres SQL qui ne s’exécutent plus.
C’est bien pour cela que cette phase peut être longue, et nécessite le recensement de très nombreuses requêtes trappées dans DBA_SQL_FIREWALL_ALLOWED_SQL.
La valeur de “SQL_SIGNATURE” est essentielle , dans la mesure ou le relevé des variables est “bindé”, les requêtes suivantes seront autorisées même si les résultats sont différents :
SQL> select name, address from application_owner.salaries where id = 510024; SQL> select name, address from application_owner.salaries where id = 285548;
Pensez également à purger la vue DBA_SQL_FIREWALL_VIOLATIONS de façon régulière, tout en portant attention sur ce qui aura été relevé durant les périodes de production.
🙂
Continuez votre lecture sur le blog :
- Installation Oracle 64 bits sur Red Hat 5 (Capdata team) [OracleVintage]
- Oracle Text pour DBA Oracle : Partie 1 (Capdata team) [Oracle]
- Le chiffrement Oracle : native network encryption (Emmanuel RAMI) [Oracle]
- Réplication logique avec PostgreSQL (Capdata team) [PostgreSQL]
- Un trigger fait-il parti d’une transaction ? (Benjamin VESAN) [GénéralMySQLOracleSQL ServerSybase]