In der heutigen Welt sind Unternehmen zunehmend einer beispiellosen Bedrohung durch Cyberangriffe auf ihre Informationsbestände ausgesetzt.
Cyberangriffe können in vielen Formen auftreten. Ein solcher Angriff wird als SQL-Injection bezeichnet . Mit SQL-Injection zielen böswillige Spieler auf die Backend-Datenbank eines beliebigen Systems ab. Normalerweise sind diese Systeme öffentlich zugänglich. Hacker versuchen, scheinbar harmlose und regelmäßige Abfragen an eine Datenbank zu senden – außer mit Parametern, die Informationen preisgeben können, die sie nicht sehen sollen, oder die Datenbank mit falschen Informationen beschädigen oder das System zum Absturz bringen können.
Cybersicherheitsspezialisten rennen immer gegen die Zeit, um der Raffinesse dieser Angriffe immer einen Schritt voraus zu sein, und wie die meisten großen Kriege wird dieser jetzt an allen Fronten ausgetragen. Das bedeutet, dass Sicherheit auf jeder Ebene des Stacks einer Anwendung implementiert werden muss – einschließlich der Datenbankebene.
Erfahrene DBAs versuchen in der Regel, Datenbanken mit Maßnahmen wie rollenbasierter Zugriffskontrolle (RBAC), föderierter Authentifizierung, Auditing oder SSL zu sichern. Es sollten jedoch auch zusätzliche Maßnahmen zur Sicherung der Datenbank in Betracht gezogen werden.
Eine solche Schutzmaßnahme ist eine Datenbank-Firewall. Wie normale Firewalls filtern Datenbank-Firewalls den Datenverkehr basierend auf einer Whitelist oder Blacklist heraus. Sie können auch aus Systemzugriffsmustern „lernen“, um zu verstehen, welchen Aussagen vertraut werden kann und welchen nicht. Die Verwendung eines Tools wie diesem fügt eine starke Schutzschicht gegen SQL-Injection hinzu.
In diesem Artikel sprechen wir über SQL-Firewall , eine Datenbank-Firewall zum Schutz von PostgreSQL-Datenbanken. SQL Firewall wird von 2ndQuadrant, einem führenden Anbieter von PostgreSQL-Technologien, erstellt und unterstützt.
Funktionsweise der SQL-Firewall
SQL Firewall ist eine Erweiterung für PostgreSQL 9.4 und höher. Obwohl es derzeit bis PostgreSQL Version 10 unterstützt wird, wird weiter daran gearbeitet, spätere Versionen zu unterstützen.
Da es sich um eine Erweiterung handelt, ist die SQL Firewall sehr einfach zu installieren und zu konfigurieren. Einmal konfiguriert, kann es verwendet werden, um SQL-Anweisungen gegen Datenbanken für einzelne Benutzer auf die Whitelist zu setzen. Das Whitelisting entsteht durch das „Training“ der Erweiterung mit der typischen Arbeitslast einer Anwendung – normalerweise durch wiederholte Durchläufe einer Reihe von Tests, die alle möglichen Szenarien abdecken. Sobald die Whitelist feinabgestimmt und abgeschlossen ist, kann sie exportiert und dann in andere PostgreSQL-Instanzen importiert werden, die ähnliche Workloads bedienen.
Beispielsweise kann jeder konfigurierte Benutzer vor dem Start einer Anwendung in einer kontrollierten Umgebung Beispiel-Workloads in Produktionsqualität für die Datenbank ausführen. Einem menschlichen Benutzerkonto kann erlaubt werden, nur schreibgeschützte Abfragen auszuführen, während einem Anwendungsbenutzerkonto erlaubt werden könnte, sowohl Lese- als auch Schreibvorgänge auszuführen. SQL Firewall setzt dann Leseabfragen sowohl für menschliche als auch Anwendungsbenutzerkonten auf die Whitelist und schreibt nur Abfragen für das Anwendungsbenutzerkonto. Wenn ein menschlicher Benutzer dann versucht, ein INSERT, DELETE oder UPDATE auszuführen, verweigert SQL Firewall den Vorgang. Wenn sich die Anwendung weiterentwickelt, kann die Whitelist auch mit der sich ändernden Arbeitslast neu trainiert werden.
Jede blockierte Anweisung wird von der SQL Firewall protokolliert, was bedeutet, dass Betriebsteams diese Protokolle an ihre Protokollverwaltungslösungen senden können und bei jeder Ausnahme benachrichtigt werden.
Einrichten der Umgebung
In diesem Artikel installieren wir SQL Firewall für eine PostgreSQL 10-Instanz mit einem Knoten, die auf Red Hat Enterprise Linux 7 ausgeführt wird. Zum Zeitpunkt der Erstellung dieses Artikels sind RHEL/CentOS 7 und PostgreSQL 10 die am höchsten unterstützten Versionen. Wie bereits erwähnt, kommt jedoch weitere Unterstützung hinzu.
Hinweis
[Bitte beachten Sie, dass SQL Firewall ein kommerziell lizenziertes Produkt ist, das Kunden mit 24/7-Support zur Verfügung steht. Es kann nicht von der öffentlichen Website von 2ndQuadrant heruntergeladen werden.]
Schritt 1:Installation von PostgreSQL 10
Unser Testsystem ist eine Amazon EC2-Instanz, auf der Red Hat Enterprise Linux 7.2 ausgeführt wird.
# cat /etc/redhat-release Red Hat Enterprise Linux Server release 7.2 (Maipo)
Wir führen den folgenden Befehl aus, um das RPM-Repository für PostgreSQL 10 (x86-64) herunterzuladen.
# yum install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm -y
Als nächstes installieren wir das Server- und das Client-Paket.
# yum install postgresql10-server postgresql10 -y
Sobald die Pakete erfolgreich installiert sind, führen wir den Befehl initdb aus, um die Datenbank zu initialisieren.
# /usr/pgsql-10/bin/postgresql-10-setup initdb Initializing database ... OK
Als nächstes nehmen wir die folgende Änderung an der Datei postgresql.conf vor. Standardmäßig befindet es sich im Verzeichnis /var/lib/pgsql/10/data/.
listen_addresses = '*'
Fügen Sie dann die folgende Zeile zur Datei pg_hba.conf hinzu (wieder standardmäßig im Verzeichnis /var/lib/pgsql/10/data/).
host all all <our IP address range> md5
Anschließend starten wir den PostgreSQL-Dienst und ermöglichen ihm den automatischen Start.
# systemctl start postgresql-10.service # systemctl enable postgresql-10.service
Abschließend melden wir uns über psql als postgres-Benutzer bei der Datenbankinstanz an und ändern das Passwort.
# su - postgres -bash-4.2$ psql psql (10.12) Type "help" for help. postgres=# \password Enter new password: Enter it again: postgres=#
Schritt 2:Beispieldatenbanken wiederherstellen
Um ein Produktionssystem zu emulieren, haben wir zwei Beispieldatenbanken in unserem PostgreSQL-Server wiederhergestellt. Diese Datenbanken sind öffentlich zugänglich:
- Pagila : die PostgreSQL-Version der beliebten MySQL-Sakila-Datenbank
- Chinook : eine Datenbank über digitale Medienspeicher
Schritt 3:Erstellen Sie Rollen und Benutzer
Mit den erstellten Datenbanken erstellen wir zwei Benutzerrollen. Einer heißt „human_user“, der andere heißt „app_user“.
Die Rolle human_user stellt jede Person dar, die vom Back-End oder mit einem Client-Tool auf die Datenbank zugreift. Die Rolle app_user stellt das Konto dar, das eine Anwendung zum Herstellen einer Verbindung mit der Datenbank verwendet.
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>';"
Den Benutzerrollen wird dann die Berechtigung erteilt, auf die Chinook- und die Pagila-Datenbank zuzugreifen, indem die folgenden Befehle als Postgres-Benutzer ausgeführt werden:
$ 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;"
Schritt 4:SQL-Firewall installieren
Die Installation von SQL Firewall ist ein unkomplizierter Vorgang. Zuerst installieren wir das Paket.
# 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%]
Dann aktualisieren wir die Datei postgresql.conf, indem wir den Parameter shared_preload_libraries ändern.
shared_preload_libraries = 'sqlfirewall'
Sobald dies erledigt ist, starten wir den PostgreSQL-Dienst neu.
# systemctl restart postgresql-10.service
Nachdem der Dienst neu gestartet wurde, melden wir uns als postgres-Benutzer bei der Instanz an und fügen die Erweiterung zu beiden Beispieldatenbanken hinzu.
$ 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
Das folgende Bild zeigt die Erweiterungen, die auf beiden Datenbanken installiert sind. Beachten Sie, dass in beiden Datenbanken auch ein spezielles Schema namens „sqlfirewall“ erstellt wird. Dieses Schema enthält alle Datenbankobjekte, die sich auf den Betrieb von SQL Firewall beziehen.
Wir können auch sehen, dass eine neue Rolle mit dem Namen „sqlfirewall_manager“ automatisch erstellt wird. Benutzer, die dieser Rolle hinzugefügt werden, können auf Funktionen und Ansichten im sqlfirewall-Schema zugreifen.
Schritt 5:Konfigurieren der SQL-Firewall
Anschließend werden der postgresql.conf eine Reihe von Parametern hinzugefügt Datei. Für Red Hat Enterprise Linux und seine abgeleiteten Distributionen ist das Standardverzeichnis für diese Datei /var/lib/pgsql/10/data/.
Im folgenden Codeausschnitt bearbeiten wir die Datei und fügen eine Reihe von Parametern hinzu.
# vim /var/lib/pgsql/10/data/postgresql.conf sqlfirewall.whitelist = 'verbose' sqlfirewall.track = 'all' sqlfirewall.track_utility = 'true' sqlfirewall.save = 'true'
Dann laden wir die gesamte Konfiguration neu.
$ 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)
Als nächstes lassen wir den Prozess für eine Sekunde schlafen.
postgres=# SELECT pg_sleep(1); pg_sleep ---------- (1 row)
und überprüfen Sie dann den Whitelisting-Status in beiden Datenbanken. Wenn die Schritte befolgt wurden, sollte für beide Datenbanken die Whitelist aktiviert sein.
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)
Lassen Sie uns die gerade hinzugefügten Parameter durchgehen.
Die sqlfirewall.whitelist Der Parameter wird verwendet, um die Whitelisting-Funktionalität der Firewall zu aktivieren. Dieser Parameter kann einen von zwei Werten haben:„verbose“ oder „protect“.
Mit der verbose-Option zeigt SQL Firewall dem Benutzer eine Warnmeldung an, wenn er versucht, eine nicht auf der weißen Liste stehende Abfrage auszuführen, dass er dazu nicht berechtigt ist. Wenn der Wert auf geschützt gesetzt ist, zeigt die SQL-Firewall eine generische „Berechtigung verweigert“-Meldung an. Als Best Practice empfehlen wir, den Wert auf „protect“ zu setzen, was dem Hacker keine Ahnung gibt, warum der Befehl abgelehnt wird. Wir haben diesen Parameter nur zu Demonstrationszwecken auf „verbose“ gesetzt.
Die der sqlfirewall.track zugewiesenen Werte und das sqlfirewall.track_utility Parameter stellen sicher, dass SQL Firewall alle Anweisungen für Whitelist-Zwecke verfolgt.
Schließlich setzen Sie die sqlfirewall.save Parameter auf „true“ stellt sicher, dass die Whitelist-Anweisungen beibehalten werden, selbst wenn der Server neu gestartet wird.
SQL-Firewall ausführen
Das Ausführen von SQL Firewall umfasst das Aufrufen einer Reihe von Funktionen, die mit der Erweiterung geliefert werden.
Schritt 1:SQL-Firewall-Funktionen verstehen
Die SQL Firewall-Erweiterung erstellt eine Reihe von Funktionen im sqlfirewall-Schema der Datenbank, in der sie installiert ist. Die meisten dieser Funktionen können nur von Superusers oder Mitgliedern der Rolle sqlfirewall_manager ausgeführt werden.
Gehen wir kurz einige dieser Funktionen durch.
sqlfirewall_whitelist_mode ist die Hauptfunktion, mit der wir arbeiten werden. Diese Funktion aktiviert das Statement-Whitelisting für einen bestimmten PostgreSQL-Benutzer. Es braucht zwei Parameter:Einer ist der Benutzername, der andere ist der whitelist_mode.
Der whitelist_mode Parameter kann drei Werte haben:
- Wenn es auf „AUFNAHME eingestellt ist “, zeichnet die SQL Firewall alle vom Benutzer ausgeführten Anweisungen in der Whitelist des Benutzers auf
- Bei Einstellung auf „ENFORCE “, erzwingt die SQL Firewall die Whitelist. Jede Anweisung, die nicht in der Whitelist enthalten ist, führt zu einem Fehler
- Der Wert von „OFF ” deaktiviert die Whitelist-Funktionalität für den Benutzer und der Benutzer kann überhaupt keine Abfragen ausführen
Wenn Sie die Whitelist-Abfragen für einen Benutzer entfernen möchten, führen Sie sqlfirewall_whitelist_delete aus funktionieren stattdessen. Diese Funktion benötigt einen einzigen Parameter:den Benutzernamen. Nach der Ausführung entfernt die Funktion sqlfirewall_whitelist_delete alle Anweisungen auf der Whitelist für den Benutzer.
Der sqlfirewall_whitelist_delete_entry Funktion wird verwendet, um einzelne Abfrage-IDs aus der Whitelist eines Benutzers zu entfernen. Dies kann nützlich sein, wenn Sie zu viele zulässige Abfragen für einen Benutzer haben und diese optimieren möchten. Die Funktion benötigt zwei Parameter:den Benutzernamen und die Abfrage-ID. Die ID der Abfrage, die Sie von der Whitelist ausschließen möchten, finden Sie in der sqlfirewall-Ansicht.
Die sqlfirewall_whitelist_users Die Funktion nimmt keinen Parameter entgegen. Es gibt eine Liste von Benutzern zurück, die Whitelisting für ihr Konto aktiviert haben.
Sie können die Whitelist für einen Benutzer mit sqlfirewall_whitelist_export exportieren Funktion. Diese Funktion benötigt zwei Parameter:den Benutzernamen und den Dateinamen, in den sie die Whitelist-Anweisungen des Benutzers exportiert. Die Datei muss sich an einem Ort befinden, auf den der PostgreSQL-Serverprozess Schreibzugriff hat.
Ähnlich wie die Funktion sqlfirewall_whitelist_export, die Funktion sqlfirewall_whitelist_import wird verwendet, um eine exportierte Whitelist-Datei für einen Benutzer in eine andere PostgreSQL-Instanz für diesen Benutzer zu importieren. Diese Funktion benötigt auch zwei Parameter, den Benutzernamen und die zu importierende Datei. Die Datei muss sich an einem Ort befinden, an dem der PostgreSQL-Serverprozess sie lesen kann.
Außerdem muss die Zieldatenbank eine binäre Kopie der Quelldatenbank sein – das heißt, das Ziel muss Teil einer Streaming-Replikation oder einer PostgreSQL-Instanz sein, die aus einer Quelle mit dem Befehl pg_basebackup erstellt wurde. Datenbanken, die aus einem logischen Dump der Quelldatenbank erstellt wurden, können die Whitelist-Datei nicht importieren – in solchen Fällen muss das Whitelisting manuell konfiguriert werden.
Schritt 2:Whitelisting für Nutzer aktivieren
Nachdem wir nun einige Ideen zu den SQL-Firewall-Funktionen haben, beginnen wir mit dem Whitelisting-Prozess für human_user und app_user in den Datenbanken pagila und chinook.
Im folgenden Code-Snippet führen wir die folgenden Befehle als Postgres-Superuser aus.
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)
Wir können dies auch bestätigen, indem wir die Funktion sqlfirewall_whitelist_users() ausführen.
$ 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)
Schritt 3:Ausführen einer Arbeitslast
Mit aktiviertem Whitelisting und Aufzeichnung wechseln wir zum Konto app_user und führen einige Abfragen wie unten gezeigt aus. Beachten Sie, wie der app_user verschiedene „ID-Felder“ (customer_id, staff_id, EmployeeID usw.) aus verschiedenen Tabellen auswählt.
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"; ...
Als nächstes wechseln wir zum human_user-Konto und führen einige einfache Abfragen für einige der Tabellen aus, auf die der app_user zugegriffen hat.
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"; ...
Wenn wir die sqlfirewall-Ansicht von einer der Datenbanken als Postgres-Benutzer abfragen, können wir die Abfragen sehen, die für jeden Benutzer auf die weiße Liste gesetzt wurden.
Schritt 4:Whitelist erzwingen
Mit einer jetzt erfassten Beispiel-Workload erzwingen wir die Whitelist für beide Benutzerkonten in beiden Datenbanken, indem wir die folgenden Befehle ausführen. Die Befehle müssen von einem Superuser ausgeführt werden; in diesem Fall führen wir diese als Benutzer postgres aus.
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)
Schritt 5:Testen
Um das Whitelisting zu testen, haben wir uns als human_user bei der pagila-Datenbank angemeldet und versucht, die zuvor ausgeführten Befehle auszuführen
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; ...
Die Befehle sind erfolgreich. Dies liegt daran, dass diese Befehle zuvor vom human_user ausgeführt wurden und auf der weißen Liste standen.
Jetzt versuchen wir, den folgenden Befehl auszuführen. Beachten Sie, wie der human_user versucht, eine Abfrage mit zwei zusätzlichen Feldern auszuführen. Diese Abfrage wurde zuvor von app_user ausgeführt.
pagila=> SELECT payment_id, customer_id, payment_date, amount FROM public.payment;
Die Anweisung schlägt mit einer Meldung wie dieser fehl:
ERROR: Execution of non-whitelisted statement prohibited
Dies geschieht, weil der human_user zuvor einen Befehl ausgeführt hatte, um nur zwei Felder aus dieser Tabelle auszuwählen, nicht die zusätzlichen Felder (Zahlungs-ID und Kunden-ID), auf die er jetzt zuzugreifen versucht. SQL Firewall hat seine vorherige Abfrage als bekannte Arbeitslast aufgezeichnet und diese Abfrage auf die Whitelist gesetzt. Als er versucht, diese beiden neuen Felder in seine Abfrage einzufügen, blockiert ihn die Firewall.
Wenn Sie darüber nachdenken, könnte ein Hacker auf diese Weise einen ID-Feldwert stehlen, damit er in der WHERE-Klausel einer anderen Abfrage verwendet werden kann, um weitere Informationen zu erhalten. Die Verwendung einer Whitelisting-Methode blockiert dies effektiv.
Was passiert also, wenn der Benutzer diese beiden zusätzlichen Felder für legitime Zwecke benötigt? In einem solchen Fall muss der Whitelist-Modus für den Benutzer wieder auf „RECORD“ geändert werden, damit die neuen Abfragen ausgeführt werden können und die SQL Firewall sie auf die Whitelist setzen kann.
Lassen Sie uns einen weiteren Test durchführen, bevor wir zum Abschluss kommen. Dieses Mal gehen wir davon aus, dass ein Hacker das Konto „app_user“ kompromittiert hat und eine Löschanweisung für die Tabelle „Zahlung“ ausführen möchte. Denken Sie daran, dass wir dem Benutzer die Berechtigungen DELETE und TRUNCATE für die Tabelle erteilt haben.
Also melden wir uns als app_user an und führen eine DELETE-Anweisung aus.
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
Schlussfolgerung
Die Aussage wird verweigert, weil sie nicht auf der weißen Liste steht. Selbst wenn der Benutzer das Recht hat, Daten aus der Tabelle zu löschen, hat die SQL Firewall dies zu Recht blockiert.
Wie Sie sehen können, ist die SQL Firewall ein leistungsstarkes Sicherheitstool. Es verfügt über Sicherheitsfunktionen, die es ermöglichen, es in einem Pseudo-Produktionsmodus zu verwenden. In diesem Modus kann ein Testbenutzer so konfiguriert werden, dass seine Anweisungen auf die Whitelist gesetzt werden, und dann kann die Funktionalität getestet werden.
DBAs und Systemadministratoren müssen jedoch einige Punkte beachten:
Zunächst einmal:Wenn der Whitelist-Modus eines Benutzers auf „RECORD“ eingestellt ist, hindert die SQL Firewall den Benutzer nicht daran, eine Abfrage auszuführen. Mit anderen Worten, die SQL Firewall muss zuerst trainiert werden, bevor sie einen Benutzer blockieren kann. Aus diesem Grund ist es wichtig sicherzustellen, dass die normalen Datenbankzugriffsrechte auch auf alle Benutzerkonten angewendet werden. Dies ist umso wichtiger, da Mitglieder der Rollen superuser und sqlfirewall_manager von den Firewall-Regeln ausgenommen sind. SQL Firewall ist kein Ersatz für vorhandene Datenbanksicherheit – sie ist dazu da, sie zu ergänzen.
Zweitens behandelt die SQL Firewall beim Whitelisting einzelner SELECT-, INSERT-, UPDATE- und DELETE-Anweisungen Objektnamen, die in diesen Befehlen verwendet werden und in unterschiedlichen Schreibweisen (Großbuchstaben, Großbuchstaben oder Kleinbuchstaben) geschrieben sind, als gleich. Alle anderen Befehle werden anhand der textuellen Abfragezeichenfolgen verglichen. So behandelt die SQL Firewall beispielsweise „BEGIN“ und „begin“ und „Begin“ als Teil separater Abfragen.
Drittens repliziert die Whitelist von SQL Firewall nicht automatisch auf Standby-Knoten in einer Replikationsumgebung. Sie können Whitelists jedoch mit der Funktion sqlfirewall_whitelist_export exportieren und mit der Funktion sqlfirewall_whitelist_import auf einen anderen Server importieren. Leider funktioniert das Sichern der Datenbank oder des sqlfirewall-Schemas und das Wiederherstellen in der Zielinstanz nicht. Außerdem muss auf dem Zielserver dasselbe Benutzerkonto vorhanden sein, damit die Whitelist nützlich ist.
Es müssen sorgfältig alle möglichen Arten von Abfragen berücksichtigt werden, die ein Benutzer für eine Datenbank durchführen kann, und das Whitelisting im „RECORD“-Modus so lange wie nötig ausführen, um alle normalen Workloads zu erfassen. Eine zu geringe Erfassung kann ein Benutzerkonto daran hindern, legitime Abfragen auszuführen, während eine zu lange Aufzeichnung unnötigerweise Befehle zur Whitelist hinzufügen kann. Dies kann zu Verzögerungen für die SQL Firewall führen, wenn sie Anweisungen im Erzwingungsmodus vergleicht.