Dans le monde d'aujourd'hui, les organisations sont de plus en plus confrontées à un niveau sans précédent de cyberattaques contre leurs actifs d'information.
Les cyberattaques peuvent prendre plusieurs formes. L'une de ces attaques est appelée injection SQL . Avec l'injection SQL, les joueurs malveillants ciblent la base de données principale de n'importe quel système. Habituellement, ces systèmes sont destinés au public. Les pirates essaient d'envoyer des requêtes apparemment anodines et régulières à une base de données, sauf avec des paramètres qui peuvent exposer des informations qu'ils ne sont pas censés voir, corrompre la base de données avec des informations erronées ou planter le système.
Les spécialistes de la cybersécurité sont toujours en course contre la montre pour garder une longueur d'avance sur la sophistication de ces attaques, et comme la plupart des grandes guerres, elles se déroulent désormais sur tous les fronts. Cela signifie que la sécurité doit être implémentée à chaque couche de la pile d'une application, y compris la couche de base de données.
Les administrateurs de bases de données expérimentés tentent généralement de sécuriser les bases de données avec des mesures telles que le contrôle d'accès basé sur les rôles (RBAC), l'authentification fédérée, l'audit ou SSL. Cependant, toute mesure supplémentaire pour sécuriser la base de données doit également être envisagée.
Une telle mesure de protection est un pare-feu de base de données. Comme les pare-feu classiques, les pare-feu de base de données filtrent le trafic en fonction d'une liste blanche ou d'une liste noire. Ils peuvent également « apprendre » des modèles d'accès au système pour comprendre quelles déclarations peuvent être approuvées et lesquelles ne le peuvent pas. L'utilisation d'un outil comme celui-ci ajoute une solide couche de protection contre l'injection SQL.
Dans cet article, nous parlerons de SQL Firewall , un pare-feu de base de données pour protéger les bases de données PostgreSQL. Le pare-feu SQL est conçu et pris en charge par 2ndQuadrant, un leader des technologies PostgreSQL.
Fonctionnement du pare-feu SQL
Le pare-feu SQL est une extension de PostgreSQL 9.4 et supérieur. Bien qu'il soit actuellement pris en charge jusqu'à la version 10 de PostgreSQL, d'autres travaux sont en cours pour prendre en charge les versions ultérieures.
S'agissant d'une extension, SQL Firewall est très simple à installer et à configurer. Une fois configuré, il peut être utilisé pour mettre en liste blanche les instructions SQL par rapport aux bases de données pour les utilisateurs individuels. La liste blanche provient de la "formation" de l'extension avec la charge de travail typique d'une application - provenant généralement d'exécutions répétées d'une suite de tests couvrant tous les scénarios possibles. Une fois la liste blanche affinée et finalisée, elle peut être exportée puis importée dans d'autres instances PostgreSQL servant des charges de travail similaires.
Par exemple, avant le lancement d'une application, chaque utilisateur configuré peut exécuter des exemples de charges de travail de qualité production sur la base de données dans un environnement contrôlé. Un compte d'utilisateur humain peut être autorisé à exécuter uniquement des requêtes en lecture seule, tandis qu'un compte d'utilisateur d'application peut être autorisé à exécuter à la fois des lectures et des écritures. Le pare-feu SQL met ensuite en liste blanche les requêtes de lecture pour les comptes d'utilisateurs humains et d'application et les requêtes d'écriture pour le compte d'utilisateur d'application uniquement. Si un utilisateur humain essaie ensuite d'exécuter un INSERT, DELETE ou UPDATE, le pare-feu SQL refusera alors l'opération. Au fur et à mesure que l'application évolue, la liste blanche peut également être recyclée avec l'évolution de la charge de travail.
Chaque instruction bloquée est consignée par le pare-feu SQL, ce qui signifie que les équipes opérationnelles peuvent envoyer ces journaux à leurs solutions de gestion des journaux et être alertées chaque fois qu'il y a une exception.
Configuration de l'environnement
Dans cet article, nous allons installer SQL Firewall pour une instance PostgreSQL 10 à nœud unique s'exécutant sur Red Hat Enterprise Linux 7. Au moment de la rédaction, RHEL/CentOS 7 et PostgreSQL 10 sont les versions les plus prises en charge. Cependant, comme mentionné précédemment, un soutien supplémentaire est en cours.
Remarque
[Veuillez noter que SQL Firewall est un produit sous licence commerciale disponible pour les clients de l'assistance 24h/24 et 7j/7. Il n'est pas disponible en téléchargement sur le site Web public de 2ndQuadrant.]
Étape 1 :Installer PostgreSQL 10
Notre système de test est une instance Amazon EC2 exécutant Red Hat Enterprise Linux 7.2.
# cat /etc/redhat-release Red Hat Enterprise Linux Server release 7.2 (Maipo)
Nous exécutons la commande suivante pour télécharger le référentiel RPM pour PostgreSQL 10 (x86-64).
# yum install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm -y
Ensuite, nous installons le serveur et le package client.
# yum install postgresql10-server postgresql10 -y
Une fois les packages installés avec succès, nous exécutons la commande initdb pour initialiser la base de données.
# /usr/pgsql-10/bin/postgresql-10-setup initdb Initializing database ... OK
Ensuite, nous apportons la modification suivante au fichier postgresql.conf. Par défaut, il se trouve sous le répertoire /var/lib/pgsql/10/data/.
listen_addresses = '*'
Et ensuite, ajoutez la ligne suivante au fichier pg_hba.conf (encore une fois, par défaut, c'est sous le répertoire /var/lib/pgsql/10/data/).
host all all <our IP address range> md5
Nous démarrons ensuite le service PostgreSQL et lui permettons de démarrer automatiquement.
# systemctl start postgresql-10.service # systemctl enable postgresql-10.service
Enfin, nous nous connectons à l'instance de base de données à partir de psql en tant qu'utilisateur postgres et modifions le mot de passe.
# su - postgres -bash-4.2$ psql psql (10.12) Type "help" for help. postgres=# \password Enter new password: Enter it again: postgres=#
Étape 2 :Restaurer les exemples de bases de données
Pour émuler un système de production, nous avons restauré deux exemples de bases de données dans notre serveur PostgreSQL. Ces bases de données sont accessibles au public :
- Page : la version PostgreSQL de la célèbre base de données MySQL Sakila
- Chinook : une base de données sur le magasin de médias numériques
Étape 3 :Créer des rôles et des utilisateurs
Avec les bases de données créées, nous créons deux rôles d'utilisateur. L'un s'appelle "human_user", l'autre s'appelle "app_user".
Le rôle human_user représente toute personne accédant à la base de données depuis le back-end ou avec un outil client. Le rôle app_user représente le compte qu'une application utilisera pour se connecter à la base de données.
psql -d postgres -c "CREATE ROLE human_user WITH NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT LOGIN NOREPLICATION PASSWORD '<a tough password>';" psql -d postgres -c "CREATE ROLE app_user WITH NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT LOGIN NOREPLICATION PASSWORD '<a tough password>';"
Les rôles d'utilisateur sont alors autorisés à accéder aux bases de données chinook et pagila en exécutant les commandes suivantes en tant qu'utilisateur postgres :
$ psql -d postgres -c "GRANT CONNECT ON DATABASE pagila, chinook TO app_user;" $ psql -d chinook -c "GRANT USAGE ON SCHEMA public TO app_user;" $ psql -d chinook -c "GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO app_user;" $ psql -d chinook -c "GRANT SELECT, INSERT, UPDATE, DELETE, TRUNCATE, TRIGGER, REFERENCES ON ALL TABLES IN SCHEMA public TO app_user;" $ psql -d chinook -c "GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO app_user;" $ psql -d pagila -c "GRANT USAGE ON SCHEMA public TO app_user;" $ psql -d pagila -c "GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO app_user;" $ psql -d pagila -c "GRANT SELECT, INSERT, UPDATE, DELETE, TRUNCATE, TRIGGER, REFERENCES ON ALL TABLES IN SCHEMA public TO app_user;" $ psql -d pagila -c "GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO app_user;" $ psql -d postgres -c "GRANT CONNECT ON DATABASE pagila, chinook TO human_user;" $ psql -d chinook -c "GRANT USAGE ON SCHEMA public TO human_user;" $ psql -d chinook -c "GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO human_user;" $ psql -d chinook -c "GRANT SELECT, INSERT, UPDATE, DELETE, TRUNCATE, TRIGGER, REFERENCES ON ALL TABLES IN SCHEMA public TO human_user;" $ psql -d chinook -c "GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO human_user;" $ psql -d pagila -c "GRANT USAGE ON SCHEMA public TO human_user;" $ psql -d pagila -c "GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO human_user;" $ psql -d pagila -c "GRANT SELECT, INSERT, UPDATE, DELETE, TRUNCATE, TRIGGER, REFERENCES ON ALL TABLES IN SCHEMA public TO human_user;" $ psql -d pagila -c "GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO human_user;"
Étape 4 :Installer le pare-feu SQL
L'installation de SQL Firewall est un processus simple. Tout d'abord, nous installons le package.
# rpm -ivh postgresql10-sqlfirewall-3.0-1.el7.x86_64.rpm warning: postgresql10-sqlfirewall-3.0-1.el7.x86_64.rpm: Header V4 RSA/SHA1 Signature, key ID ******: NOKEY Preparing... ################################# [100%] Updating / installing... 1:postgresql10-sqlfirewall-3.0-1.el################################# [100%]
Ensuite, nous mettons à jour le fichier postgresql.conf en modifiant le paramètre shared_preload_libraries.
shared_preload_libraries = 'sqlfirewall'
Une fois cela fait, nous redémarrons le service PostgreSQL.
# systemctl restart postgresql-10.service
Une fois le service redémarré, nous nous connectons à l'instance en tant qu'utilisateur postgres et ajoutons l'extension aux deux exemples de bases de données.
$ psql -U postgres -d chinook -c "CREATE EXTENSION sqlfirewall;" Password for user postgres: CREATE EXTENSION -bash-4.2$ psql -U postgres -d pagila -c "CREATE EXTENSION sqlfirewall;" Password for user postgres: CREATE EXTENSION
L'image ci-dessous montre les extensions installées sur les deux bases de données. Notez qu'il existe un schéma spécial appelé "sqlfirewall" également créé dans les deux bases de données. Ce schéma contient tous les objets de la base de données liés au fonctionnement du pare-feu SQL.
Nous pouvons également voir qu'un nouveau rôle nommé "sqlfirewall_manager" est automatiquement créé. Les utilisateurs ajoutés à ce rôle peuvent accéder aux fonctions et aux vues du schéma sqlfirewall.
Étape 5 :Configuration du pare-feu SQL
Un certain nombre de paramètres sont ensuite ajoutés au postgresql.conf dossier. Pour Red Hat Enterprise Linux et ses distributions dérivées, l'emplacement du répertoire par défaut pour ce fichier est /var/lib/pgsql/10/data/.
Dans l'extrait de code suivant, nous modifions le fichier et ajoutons un certain nombre de paramètres.
# vim /var/lib/pgsql/10/data/postgresql.conf sqlfirewall.whitelist = 'verbose' sqlfirewall.track = 'all' sqlfirewall.track_utility = 'true' sqlfirewall.save = 'true'
Ensuite, nous rechargeons toute la configuration.
$ psql -U postgres -d postgres Password for user postgres: psql (10.12) Type "help" for help. postgres=# SELECT pg_reload_conf(); pg_reload_conf ---------------- t (1 row)
Ensuite, nous laissons le processus dormir pendant une seconde.
postgres=# SELECT pg_sleep(1); pg_sleep ---------- (1 row)
puis vérifiez l'état de la liste blanche dans les deux bases de données. Si les étapes ont été suivies, les deux bases de données devraient avoir la liste blanche activée.
postgres=# \connect pagila You are now connected to database "pagila" as user "postgres". pagila=# show sqlfirewall.whitelist; sqlfirewall.whitelist ----------------------- verbose (1 row) pagila=# \connect chinook; You are now connected to database "chinook" as user "postgres". chinook=# show sqlfirewall.whitelist; sqlfirewall.whitelist ----------------------- verbose (1 row)
Passons en revue les paramètres que nous venons d'ajouter.
La sqlfirewall.whitelist Le paramètre est utilisé pour activer la fonctionnalité de liste blanche du pare-feu. Ce paramètre peut prendre l'une des deux valeurs suivantes :"verbose" ou "protect".
Avec l'option détaillée, le pare-feu SQL affichera un message d'avertissement à l'utilisateur lorsqu'il essaiera d'exécuter une requête non inscrite sur la liste blanche, indiquant qu'il n'est pas autorisé à le faire. Lorsque la valeur est définie sur protected, le pare-feu SQL affichera un message générique "autorisation refusée". Comme meilleure pratique, nous vous recommandons de définir la valeur sur "protéger", ce qui ne donne aucune idée au pirate pourquoi la commande est rejetée. Nous avons défini ce paramètre sur "verbeux" à des fins de démonstration uniquement.
Les valeurs attribuées à sqlfirewall.track et le sqlfirewall.track_utility garantissent que le pare-feu SQL suit toutes les instructions à des fins de liste blanche.
Enfin, définir le sqlfirewall.save paramètre sur "true" garantit que les instructions de la liste blanche sont conservées même si le serveur est redémarré.
Exécution du pare-feu SQL
L'exécution de SQL Firewall implique l'appel d'un certain nombre de fonctions fournies avec l'extension.
Étape 1 :Comprendre les fonctions du pare-feu SQL
L'extension SQL Firewall crée un certain nombre de fonctions dans le schéma sqlfirewall de la base de données où elle est installée. La plupart de ces fonctions ne peuvent être exécutées que par des superutilisateurs ou des membres du rôle sqlfirewall_manager.
Passons rapidement en revue certaines de ces fonctions.
sqlfirewall_whitelist_mode est la fonction principale avec laquelle nous allons travailler. Cette fonction active la liste blanche des instructions pour un utilisateur PostgreSQL particulier. Il prend deux paramètres :l'un est le nom d'utilisateur, l'autre est le whitelist_mode.
Le whitelist_mode paramètre peut avoir trois valeurs :
- Lorsqu'il est défini sur "ENREGISTRER ", SQL Firewall enregistrera toutes les instructions exécutées par l'utilisateur dans la liste blanche de l'utilisateur
- Lorsqu'il est défini sur "ENFORCE ”, SQL Firewall appliquera la liste blanche. Toute déclaration non incluse dans la liste blanche entraînera une erreur
- La valeur de "OFF " désactive la fonctionnalité de liste blanche pour l'utilisateur, et l'utilisateur ne pourra plus exécuter de requêtes du tout
Si vous souhaitez supprimer les requêtes de la liste blanche pour un utilisateur, exécutez la commande sqlfirewall_whitelist_delete fonction à la place. Cette fonction prend un seul paramètre :le nom d'utilisateur. Une fois exécutée, la fonction sqlfirewall_whitelist_delete supprime toutes les instructions de la liste blanche pour l'utilisateur.
Le sqlfirewall_whitelist_delete_entry La fonction est utilisée pour supprimer des ID de requête individuels de la liste blanche d'un utilisateur. Cela peut être utile lorsque vous avez trop de requêtes autorisées pour un utilisateur et que vous souhaitez l'affiner. La fonction prend deux paramètres :le nom d'utilisateur et l'ID de la requête. Vous pouvez trouver l'ID de la requête que vous souhaitez exclure de la liste blanche en consultant la vue sqlfirewall.
Les sqlfirewall_whitelist_users fonction ne prend aucun paramètre. Il renvoie une liste d'utilisateurs pour lesquels la liste blanche est activée pour leur compte.
Vous pouvez exporter la liste blanche d'un utilisateur à l'aide de sqlfirewall_whitelist_export une fonction. Cette fonction prend deux paramètres :le nom d'utilisateur et le nom du fichier où elle exporte les déclarations de l'utilisateur sur la liste blanche. Le fichier doit se trouver à un emplacement auquel le processus du serveur PostgreSQL a accès en écriture.
Semblable à la fonction sqlfirewall_whitelist_export, la fonction sqlfirewall_whitelist_import est utilisé pour importer un fichier de liste blanche exporté pour un utilisateur vers une instance PostgreSQL différente pour cet utilisateur. Cette fonction prend également deux paramètres, le nom d'utilisateur et le fichier à importer. Le fichier doit se trouver à un emplacement où le processus du serveur PostgreSQL peut le lire.
De plus, la base de données cible doit être une copie binaire de la base de données source - cela signifie que la cible doit faire partie d'une réplication en continu ou d'une instance PostgreSQL créée à partir d'une source avec la commande pg_basebackup. Les bases de données créées à partir d'un vidage logique de la base de données source ne peuvent pas importer le fichier de liste blanche - dans de tels cas, la liste blanche doit être configurée manuellement.
Étape 2 :Activer la liste blanche pour les utilisateurs
Maintenant que nous avons quelques idées sur les fonctions du pare-feu SQL, commençons le processus de liste blanche pour human_user et app_user dans les bases de données pagila et chinook.
Dans l'extrait de code ci-dessous, nous exécutons les commandes suivantes en tant que superutilisateur postgres.
postgres=# \connect pagila You are now connected to database "pagila" as user "postgres". pagila=# SELECT sqlfirewall.sqlfirewall_whitelist_mode('human_user', 'RECORD'); sqlfirewall_whitelist_mode ---------------------------- t (1 row) pagila=# SELECT sqlfirewall.sqlfirewall_whitelist_mode('app_user', 'RECORD');\ sqlfirewall_whitelist_mode ---------------------------- t (1 row) pagila=# \connect chinook You are now connected to database "chinook" as user "postgres". chinook=# SELECT sqlfirewall.sqlfirewall_whitelist_mode('human_user', 'RECORD'); sqlfirewall_whitelist_mode ---------------------------- t (1 row) chinook=# SELECT sqlfirewall.sqlfirewall_whitelist_mode('app_user', 'RECORD'); sqlfirewall_whitelist_mode ---------------------------- t (1 row)
Nous pouvons également confirmer en exécutant la fonction sqlfirewall_whitelist_users().
$ psql -U postgres -d pagila -c "SELECT sqlfirewall.sqlfirewall_whitelist_users();" Password for user postgres: sqlfirewall_whitelist_users ----------------------------- (17479,human_user,RECORD) (17480,app_user,RECORD) (2 rows) $ psql -U postgres -d chinook -c "SELECT sqlfirewall.sqlfirewall_whitelist_users();" Password for user postgres: sqlfirewall_whitelist_users ----------------------------- (17479,human_user,RECORD) (17480,app_user,RECORD) (2 rows)
Étape 3 :Exécuter une charge de travail
Avec la liste blanche activée et l'enregistrement, nous passons au compte app_user et exécutons quelques requêtes comme indiqué ci-dessous. Remarquez comment l'app_user sélectionne divers "champs d'identification" (customer_id, staff_id, EmployeeID, etc.) à partir de différentes tables.
postgres=# \c - app_user Password for user app_user: You are now connected to database "postgres" as user "app_user". postgres=> \connect pagila You are now connected to database "pagila" as user "app_user". pagila=> SELECT customer_id, first_name, last_name, email FROM public.customer; ... pagila=> SELECT payment_id, customer_id, payment_date, amount FROM public.payment; ... pagila=> SELECT staff_id, first_name, last_name, email FROM public.staff; ... pagila=> \connect chinook; You are now connected to database "chinook" as user "app_user". chinook=> SELECT "CustomerId", "FirstName", "LastName", "Phone" FROM public."Customer"; ... chinook=> SELECT "EmployeeId", "FirstName", "LastName", "Phone", "Email" FROM public."Employee"; ...
Ensuite, nous passons au compte human_user et exécutons quelques requêtes simples sur certaines des tables auxquelles app_user a accédé.
postgres=# \c - human_user Password for user human_user: You are now connected to database "postgres" as user "human_user". postgres=> \connect pagila; You are now connected to database "pagila" as user "human_user". pagila=> SELECT payment_date, amount FROM public.payment; ... pagila=> SELECT first_name, last_name, email FROM public.customer; ... pagila=> \connect chinook; You are now connected to database "chinook" as user "human_user". chinook=> SELECT "FirstName", "LastName", "Phone", "Email" FROM public."Employee"; ...
Si nous interrogeons la vue sqlfirewall à partir de l'une des bases de données en tant qu'utilisateur postgres, nous pouvons voir les requêtes qui ont été ajoutées à la liste blanche pour chaque utilisateur.
Étape 4 :Appliquer la liste blanche
Avec un exemple de charge de travail maintenant capturé, nous appliquons la liste blanche pour les deux comptes d'utilisateurs dans les deux bases de données en exécutant les commandes suivantes. Les commandes doivent être exécutées par un superutilisateur; dans ce cas, nous les exécutons en tant qu'utilisateur postgres.
postgres=# \connect pagila; You are now connected to database "pagila" as user "postgres". pagila=# SELECT sqlfirewall.sqlfirewall_whitelist_mode('human_user', 'ENFORCE'); sqlfirewall_whitelist_mode ---------------------------- t (1 row) pagila=# SELECT sqlfirewall.sqlfirewall_whitelist_mode('app_user', 'ENFORCE'); sqlfirewall_whitelist_mode ---------------------------- t (1 row) pagila=# \connect chinook; You are now connected to database "chinook" as user "postgres". chinook=# SELECT sqlfirewall.sqlfirewall_whitelist_mode('human_user', 'ENFORCE'); sqlfirewall_whitelist_mode ---------------------------- t (1 row) chinook=# SELECT sqlfirewall.sqlfirewall_whitelist_mode('app_user', 'ENFORCE'); sqlfirewall_whitelist_mode ---------------------------- t (1 row)
Étape 5 :Tests
Pour tester la liste blanche, nous nous sommes connectés à la base de données pagila en tant que human_user et avons essayé d'exécuter les commandes qui étaient exécutées auparavant
chinook=# \c - human_user; Password for user human_user: You are now connected to database "chinook" as user "human_user". chinook=> \connect pagila; You are now connected to database "pagila" as user "human_user". pagila=> SELECT payment_date, amount FROM public.payment; ... pagila=> SELECT first_name, last_name, email FROM public.customer; ...
Les commandes réussissent. C'est parce que ces commandes étaient exécutées par le human_user auparavant et étaient sur la liste blanche.
Maintenant, nous essayons d'exécuter la commande suivante. Notez comment le human_user essaie d'exécuter une requête avec deux champs supplémentaires. Cette requête a déjà été exécutée par app_user.
pagila=> SELECT payment_id, customer_id, payment_date, amount FROM public.payment;
L'instruction échoue avec un message comme celui-ci :
ERROR: Execution of non-whitelisted statement prohibited
Cela se produit parce que human_user avait précédemment exécuté une commande pour sélectionner uniquement deux champs de cette table, et non les champs supplémentaires (ID de paiement et ID client) auxquels il essaie d'accéder maintenant. Le pare-feu SQL a enregistré sa requête précédente en tant que charge de travail connue et a ajouté cette requête à la liste blanche. Alors qu'il essaie d'ajouter ces deux nouveaux champs dans sa requête, le pare-feu le bloque.
Si vous y réfléchissez, c'est ainsi qu'un pirate pourrait vouloir voler une valeur de champ ID afin qu'elle puisse être utilisée dans la clause WHERE d'une autre requête pour obtenir des informations supplémentaires. L'utilisation d'une méthode de liste blanche bloque efficacement cela.
Alors, que se passe-t-il si l'utilisateur a besoin de ces deux champs supplémentaires à des fins légitimes ? Dans ce cas, le mode de liste blanche de l'utilisateur doit être redéfini sur "ENREGISTRER" afin que les nouvelles requêtes puissent s'exécuter et que le pare-feu SQL puisse les ajouter à la liste blanche.
Faisons un autre test avant de conclure. Cette fois, nous supposerons qu'un pirate informatique a compromis le compte app_user et souhaite exécuter une instruction de suppression sur la table « paiement ». Rappelez-vous que nous avions accordé à l'utilisateur les privilèges DELETE et TRUNCATE sur la table.
Nous nous connectons donc en tant que app_user et exécutons une instruction DELETE.
pagila=> \c - app_user Password for user app_user: You are now connected to database "pagila" as user "app_user". pagila=> DELETE FROM public.payment; ERROR: Execution of non-whitelisted statement prohibited
Conclusion
La déclaration est refusée car elle n'est pas sur la liste blanche. Même lorsque l'utilisateur a le droit de supprimer des données de la table, le pare-feu SQL l'a bloqué à juste titre.
Comme vous pouvez le voir, SQL Firewall est un puissant outil de sécurité. Il possède des caractéristiques de sécurité qui lui permettent d'être utilisé sur un mode de pseudo-production. Dans ce mode, un utilisateur de test peut être configuré pour que ses déclarations soient ajoutées à la liste blanche, puis la fonctionnalité peut être testée.
Les administrateurs de base de données et les administrateurs système doivent toutefois être conscients de certains points :
Tout d'abord, lorsque le mode de liste blanche d'un utilisateur est défini sur "RECORD", le pare-feu SQL n'empêche pas l'utilisateur d'exécuter une requête. En d'autres termes, le pare-feu SQL doit d'abord être formé avant de pouvoir bloquer un utilisateur. C'est pourquoi il est important de s'assurer que les privilèges d'accès normaux à la base de données sont également appliqués à tout compte d'utilisateur. Ceci est d'autant plus important que les membres des rôles superuser et sqlfirewall_manager sont exemptés des règles de pare-feu. Le pare-feu SQL ne remplace pas la sécurité de base de données existante - il est là pour la compléter.
Deuxièmement, lors de la mise en liste blanche d'instructions SELECT, INSERT, UPDATE et DELETE individuelles, le pare-feu SQL traitera les noms d'objet utilisés dans ces commandes écrits dans des casses différentes (majuscules, casse mixte ou minuscules) comme identiques. Toutes les autres commandes seront comparées sur la base des chaînes de requête textuelles. Ainsi, par exemple, SQL Firewall traitera "BEGIN" et "begin" et "Begin" comme faisant partie de requêtes distinctes.
Troisièmement, la liste blanche de SQL Firewall ne se réplique pas automatiquement sur les nœuds de secours dans un environnement de réplication. Cependant, vous pouvez exporter des listes blanches à l'aide de la fonction sqlfirewall_whitelist_export et les importer sur un autre serveur à l'aide de la fonction sqlfirewall_whitelist_import. Malheureusement, la sauvegarde de la base de données ou du schéma sqlfirewall et la restauration dans l'instance cible ne fonctionneront pas. De plus, le serveur cible doit avoir le même compte utilisateur présent pour que la liste blanche soit utile.
Il faut examiner attentivement tous les types de requêtes possibles qu'un utilisateur peut effectuer sur une base de données et exécuter la liste blanche en mode "RECORD" aussi longtemps que nécessaire pour capturer toutes les charges de travail normales. Trop peu de capture peut empêcher un compte d'utilisateur d'exécuter des requêtes légitimes, tandis qu'un enregistrement trop long peut ajouter inutilement des commandes à la liste blanche. Cela peut entraîner des retards pour le pare-feu SQL lorsqu'il compare les instructions en mode d'application.