"Datenbanksicherheit ist wie ein gutes Passwort: Du kannst dir den kompliziertesten Schlüssel ausdenken, aber wenn du ihn auf einen Zettel schreibst und an den Monitor klebst – bringt das gar nix." Unsere Aufgabe ist also nicht nur, Schutzmechanismen einzurichten, sondern auch die typischen Fehler zu vermeiden, die alle Mühe zunichte machen können.
1. Rollen mit zu vielen Rechten verwenden
Oft haben Entwickler Angst, den Zugriff einzuschränken, und erstellen Rollen mit zu vielen Privilegien, zum Beispiel mit SUPERUSER oder ALL PRIVILEGES. Das Argument klingt dann so: "Man weiß ja nie, vielleicht braucht man's mal!". Aber Rollen mit zu vielen Rechten sind ein riesiges Sicherheitsloch.
Beispiel für zu viele Rechte:
GRANT ALL PRIVILEGES ON DATABASE university TO student_role;
In diesem Fall bekommt student_role vollen Zugriff auf alle Daten in der Datenbank. Selbst wenn die Rolle eigentlich nur lesen sollte, kann sie jetzt Tabellen löschen, die Struktur ändern und sogar dem Admin den Zugriff entziehen.
Wie vermeidest du das?
Erstelle Rollen mit dem minimal nötigen Satz an Rechten. Das nennt man das Prinzip der minimalen Privilegien. Zum Beispiel sollte eine Rolle zum Lesen so aussehen:GRANT CONNECT ON DATABASE university TO student_role;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO student_role;
Mit diesem Ansatz ist klar definiert, was die Rolle student_role darf: sich verbinden und nur lesen.
2. Fehlende Verschlüsselung sensibler Daten
Stell dir die Tabelle users vor, in der wir Passwörter im Klartext speichern:
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username TEXT NOT NULL,
password TEXT NOT NULL
);
Wenn ein Angreifer Zugriff auf diese Tabelle bekommt, hat er alle Passwörter. Das ist wie den Wohnungsschlüssel unter die Fußmatte zu legen.
Um das zu vermeiden, nutze Passwortverschlüsselung mit pgcrypto. Zum Beispiel:
CREATE EXTENSION IF NOT EXISTS pgcrypto;
INSERT INTO users (username, password)
VALUES ('johndoe', pgp_sym_encrypt('sicheres_passwort', 'encryption_key'));
Zum Überprüfen des Passworts kannst du Entschlüsselung verwenden:
SELECT username
FROM users
WHERE pgp_sym_decrypt(password::BYTEA, 'encryption_key') = 'sicheres_passwort';
Speichere niemals sensible Infos im Klartext!
3. SQL-Injections ignorieren
SQL-Injections sind immer noch eine der häufigsten Angriffsarten, weil Entwickler weiterhin Abfragen mit String-Interpolation bauen. Hier ein Beispiel:
DO $$
DECLARE
username TEXT := 'John';
query TEXT;
BEGIN
query := 'SELECT * FROM users WHERE username = ''' || username || ''';';
EXECUTE query;
END $$;
Wenn ein Angreifer statt des Usernamens John' OR '1'='1 eingibt, werden alle Daten aus der Tabelle users geleakt.
Wie vermeidest du das? Nutze parametrisierte Abfragen:
PREPARE user_query (TEXT) AS
SELECT * FROM users WHERE username = $1;
EXECUTE user_query('John');
Hier wird die Variable sicher eingesetzt, Injection ausgeschlossen.
4. Falsche Konfiguration von pg_hba.conf
pg_hba.conf ist das Haupttool zur Zugriffskontrolle nach IP-Adressen. Fehler in der Konfiguration können dazu führen, dass der Zugriff viel zu offen ist.
Beispiel für eine schlechte Konfiguration:
host all all 0.0.0.0/0 trust
Diese Zeile erlaubt jedem User, sich von jeder IP ohne Passwort mit jeder Datenbank zu verbinden.
Wie vermeidest du das? Erlaube Zugriff nur für bestimmte IPs und nutze Authentifizierungsmethoden wie md5 oder scram-sha-256:
host university student_role 192.168.1.0/24 md5
Damit kann student_role nur aus dem lokalen Netz mit Passwort zugreifen.
Nach Änderungen an pg_hba.conf nicht vergessen, sie mit folgendem Befehl zu übernehmen:
pg_ctl reload
5. Falsche Nutzung von ROW LEVEL SECURITY
RLS ist ein mächtiges Tool, aber nutzlos, wenn es falsch konfiguriert oder vergessen wird zu aktivieren. Selbst wenn du eine Policy schreibst, funktioniert sie nicht, wenn RLS aus ist:
CREATE POLICY meine_policy ON users
USING (username = current_user);
-- Aber RLS ist nicht aktiviert!
SELECT * FROM users; -- Alle Zeilen werden angezeigt!
Wie vermeidest du das? Vergiss nicht, RLS zu aktivieren:
ALTER TABLE users ENABLE ROW LEVEL SECURITY;
Und prüfe, wie die Policy wirkt:
SET ROLE student_role;
SELECT * FROM users; -- Nur Zeilen, die zur Policy passen, sind sichtbar.
6. Nicht berücksichtigte Admin-Aktionen
Manchmal haben Datenbank-Admins vollen Zugriff auf alle Daten, auch wenn sie das für ihre Arbeit gar nicht brauchen. Das ist ein zusätzliches Risiko, falls das Admin-Konto kompromittiert wird.
Wie vermeidest du das? Trenne die Rollen. Für Admin-Aufgaben erstelle eine eigene Rolle ohne Datenzugriff:
CREATE ROLE admin_role WITH LOGIN CREATEDB CREATEROLE;
Für den Datenzugriff eine andere Rolle mit minimalen Rechten:
CREATE ROLE data_analyst_role;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO data_analyst_role;
Weise die Rollen je nach Aufgabe zu:
GRANT admin_role TO some_user;
GRANT data_analyst_role TO another_user;
7. Unzureichendes Logging
Wenn du kein Logging einrichtest, merkst du von verdächtigen Aktionen erst was, wenn es zu spät ist.
Beispiel für fehlendes Logging:
-- Keine Einstellungen in postgresql.conf
log_statement = 'none';
Wie vermeidest du das? Aktiviere wenigstens grundlegendes Logging:
log_statement = 'all'
log_connections = on
log_disconnections = on
So siehst du alle ausgeführten Abfragen, Verbindungen und Trennungen.
Du kannst auch mit dem pgAudit-Extension ein detailliertes Audit einrichten:
CREATE EXTENSION pgaudit;
8. Veraltete Authentifizierungsmethoden verwenden
Veraltete Authentifizierungsmethoden wie password bieten keinen ausreichenden Schutz.
Wie vermeidest du das? Stelle auf sichere Methoden wie scram-sha-256 um:
ALTER SYSTEM SET password_encryption = 'scram-sha-256';
Und aktualisiere die Passwörter der User:
ALTER USER student_role WITH PASSWORD 'neues_sicheres_passwort';
Diese Probleme wirken vielleicht klein, aber jeder einzelne kann zu einem fetten Sicherheitsleck werden. Deine Aufgabe ist es, die Datenbank so zu betreiben, als wäre jeder User, der sich verbinden will, verdächtig. Wie man so schön sagt: "Vertrau, aber prüfe." Jetzt hast du die Tools, um nicht nur die Sicherheit einzurichten, sondern auch die häufigsten Fehler zu vermeiden. Viel Erfolg und halte deine Daten sicher!
GO TO FULL VERSION