Datenbank-Sicherheit: SQL Server, MySQL und PostgreSQL absichern
Praxisguide zur Datenbank-Sicherheit: Härtung von SQL Server, MySQL und PostgreSQL, Zugriffscontrolle und Least Privilege, Audit-Logging, Verschlüsselung at rest und in transit, SQL-Injection-Schutz und Datenbank-Monitoring. Mit konkreten SQL-Befehlen und Konfigurationsbeispielen.
Inhaltsverzeichnis (6 Abschnitte)
Datenbanken sind das wertvollste Ziel in jedem Unternehmen: Kundendaten, Finanzdaten, Passwort-Hashes, Geschäftsgeheimnisse. Gleichzeitig sind Datenbanken häufig schlecht gesichert - Default-Konfigurationen, zu weitreichende Berechtigungen und fehlende Verschlüsselung sind die Norm. Dieser Guide zeigt die wichtigsten Sicherheitsmaßnahmen für die drei verbreitetsten Datenbanksysteme.
Häufige Datenbank-Sicherheitsprobleme
Typische Findings in Datenbank-Sicherheitsassessments gliedern sich in vier Bereiche:
Authentifizierung: Root- oder SA-Account aktiv und erreichbar, schwache Default-Passwörter (root/root, sa/password), Passwörter im Klartext in Config-Dateien, gemeinsame Credentials für alle Anwendungen, fehlende MFA für administrative Zugänge.
Autorisierung: Anwendungsbenutzer mit GRANT ALL oder DBA-Rechten, fehlende Schema-Level-Beschränkungen sodass die App Tabellen liest die sie nicht braucht, öffentlich zugänglicher DB-Port (3306, 5432, 1433 direkt aus dem Internet).
Verschlüsselung: Kein TLS für Verbindungen (Klartext-Übertragung), keine Verschlüsselung at rest, Passwörter als MD5 oder SHA1 gespeichert ohne Salt.
Logging: Kein Audit-Log, fehlende Erkennung von Datenbankdumps (SELECT * FROM kunden WHERE 1=1), Logs werden nicht zentral gespeichert (SIEM-Integration fehlt) und kein Patching-Prozess für Datenbankserver.
PostgreSQL Härtung
Die wichtigsten Einstellungen in postgresql.conf:
# Verbindungen einschränken:
listen_addresses = '127.0.0.1' # Nur localhost! Kein 0.0.0.0!
port = 5432
max_connections = 100
# SSL erzwingen:
ssl = on
ssl_cert_file = '/etc/postgresql/server.crt'
ssl_key_file = '/etc/postgresql/server.key'
ssl_min_protocol_version = 'TLSv1.2'
ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL'
# Logging (für Audit):
log_connections = on
log_disconnections = on
log_duration = on
log_statement = 'ddl'
log_min_duration_statement = 1000
log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h '
log_destination = 'csvlog'
logging_collector = on
Client-Authentifizierung in pg_hba.conf:
# TYPE DATABASE USER ADDRESS METHOD
local all postgres peer
host myapp myappuser 10.0.1.0/24 scram-sha-256
host all all 0.0.0.0/0 reject
Benutzer und Berechtigungen mit Least Privilege:
REVOKE CONNECT ON DATABASE myapp FROM PUBLIC;
CREATE USER myapp_user WITH PASSWORD 'StarkesPW123!';
GRANT CONNECT ON DATABASE myapp TO myapp_user;
GRANT USAGE ON SCHEMA public TO myapp_user;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO myapp_user;
GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO myapp_user;
-- Read-Only-User für Reporting:
CREATE USER reporting_user WITH PASSWORD 'ReadOnly456!';
GRANT CONNECT ON DATABASE myapp TO reporting_user;
GRANT USAGE ON SCHEMA public TO reporting_user;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO reporting_user;
-- Row-Level Security (RLS) für Multi-Tenant:
ALTER TABLE kunden ENABLE ROW LEVEL SECURITY;
CREATE POLICY kunden_tenant_policy ON kunden
USING (tenant_id = current_setting('app.tenant_id')::INT);
-- Passwort-Hashing: scram-sha-256 statt MD5:
ALTER SYSTEM SET password_encryption = 'scram-sha-256';
SELECT pg_reload_conf();
MySQL/MariaDB Härtung
Nach der Installation sollte zunächst mysql_secure_installation ausgeführt werden, um Root-Passwort zu setzen, anonyme Benutzer zu entfernen, Remote-Root-Login zu deaktivieren, die Test-Datenbank zu entfernen und Privileges neu zu laden.
Wichtige Einstellungen in /etc/mysql/mysql.conf.d/mysqld.cnf:
[mysqld]
bind-address = 127.0.0.1
local-infile = 0
skip-symbolic-links
secure-file-priv = /var/lib/mysql-files
sql_mode = "STRICT_ALL_TABLES,NO_AUTO_CREATE_USER"
ssl-ca = /etc/mysql/ca.pem
ssl-cert = /etc/mysql/server-cert.pem
ssl-key = /etc/mysql/server-key.pem
require_secure_transport = ON
general_log = OFF
log_error = /var/log/mysql/error.log
slow_query_log = ON
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2
Benutzer-Härtung:
DROP USER IF EXISTS ''@'localhost';
DROP USER IF EXISTS ''@'hostname';
DROP USER IF EXISTS 'root'@'%';
UPDATE mysql.user SET host='localhost' WHERE user='root';
FLUSH PRIVILEGES;
CREATE USER 'webapp'@'10.0.1.%' IDENTIFIED BY 'StarkesPW!';
GRANT SELECT, INSERT, UPDATE, DELETE ON myapp.* TO 'webapp'@'10.0.1.%';
INSTALL PLUGIN validate_password SONAME 'validate_password.so';
SET GLOBAL validate_password_policy=STRONG;
SET GLOBAL validate_password_length=12;
-- Audit-Logging (MariaDB):
INSTALL PLUGIN server_audit SONAME 'server_audit';
SET GLOBAL server_audit_logging=ON;
SET GLOBAL server_audit_events='CONNECT,QUERY_DDL';
Microsoft SQL Server Härtung
-- SA-Account deaktivieren oder umbenennen:
ALTER LOGIN sa DISABLE;
-- Alternativ: umbenennen und starkes Passwort setzen
ALTER LOGIN sa WITH NAME = [sqlbackup_only];
ALTER LOGIN sqlbackup_only WITH PASSWORD = 'StarkesLangesPasswort!2024';
-- xp_cmdshell deaktivieren (ermöglicht OS-Befehle über SQL):
EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 0; RECONFIGURE;
-- Transparent Data Encryption (TDE) aktivieren:
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'Verschlüsselungspasswort!';
CREATE CERTIFICATE ServerCert WITH SUBJECT = 'TDE Certificate';
CREATE DATABASE ENCRYPTION KEY
WITH ALGORITHM = AES_256
ENCRYPTION BY SERVER CERTIFICATE ServerCert;
ALTER DATABASE MyDatabase SET ENCRYPTION ON;
-- Least Privilege für Anwendungsbenutzer:
CREATE LOGIN AppUser WITH PASSWORD = 'SicheresPasswort123!';
USE MyDatabase;
CREATE USER AppUser FOR LOGIN AppUser;
GRANT SELECT, INSERT, UPDATE, DELETE ON SCHEMA::dbo TO AppUser;
DENY EXECUTE ON xp_cmdshell TO AppUser;
-- Audit:
CREATE SERVER AUDIT MyAudit TO FILE (FILEPATH = 'C:\SQLAudit\');
CREATE DATABASE AUDIT SPECIFICATION MyDBSpec
FOR SERVER AUDIT MyAudit
ADD (SELECT, INSERT, UPDATE, DELETE ON SCHEMA::dbo BY public);
ALTER SERVER AUDIT MyAudit WITH (STATE = ON);
ALTER DATABASE AUDIT SPECIFICATION MyDBSpec WITH (STATE = ON);
Remote-Verbindungen werden über den SQL Server Configuration Manager eingeschränkt: TCP/IP Properties → IP Addresses → Specific IPs konfigurieren. Nur Windows Authentication (keine SQL Authentication) ist die sicherste Konfiguration für Windows-Umgebungen.
SQL Injection Prevention - Code-Level
SQL Injection ist die häufigste Datenbankbedrohung (OWASP A03:2021). Das Grundproblem ist String-Konkatenation, bei der Benutzereingaben direkt in SQL-Queries eingebaut werden. Die Lösung sind Prepared Statements:
# Python - FALSCH:
query = "SELECT * FROM users WHERE name = '" + user_input + "'"
cursor.execute(query)
# Python - RICHTIG:
query = "SELECT * FROM users WHERE name = %s"
cursor.execute(query, (user_input,))
Dasselbe Prinzip gilt für alle Sprachen: Java JDBC verwendet PreparedStatement mit setString(), Node.js/pg verwendet parametrisierte Queries mit $1, PHP PDO verwendet prepare() mit benannten Parametern.
ORMs wie Prisma, Sequelize, Hibernate oder Entity Framework generieren Prepared Statements automatisch - aber Raw Queries in ORMs können noch anfällig sein. Stored Procedures sind nur sicher wenn sie parametrisiert sind und kein dynamisches SQL verwenden.
Als zweite Verteidigungslinie empfiehlt sich Input-Validierung: Typ-Prüfung (ist ID wirklich eine Zahl?), Whitelist erlaubter Zeichen, Längenbegrenzung. Kein Blacklist-Ansatz - Angreifer finden immer Wege um ihn zu umgehen.
Datenbank-Monitoring und Audit
Folgende Ereignisse müssen überwacht werden: alle Logins (Erfolg und Fehler), privilegierte Aktionen (GRANT, DROP, ALTER), Datenzugriffe auf sensitive Tabellen, Massenabfragen als mögliche Dump-Indikatoren, Verbindungen von ungewöhnlichen IPs, Aktivität außerhalb der Geschäftszeiten und Schema-Änderungen.
SIEM-Integration über Filebeat für MySQL-Logs und entsprechende Elasticsearch-Alerts auf Dump-Muster ermöglichen frühzeitige Erkennung. Database Activity Monitoring (DAM) Tools wie IBM Guardium oder Imperva Database Security bieten Real-Time-Erkennung von SQL-Injection-Mustern, Verhaltensbaseline, automatisches Blockieren und DSGVO-konforme Protokollierung. Für PostgreSQL bietet pgAudit eine Open-Source-Option.
Backup-Sicherheit erfordert: Backups verschlüsselt (mysqldump | gpg -e > backup.sql.gpg), Backup-Server getrennt vom Produktionsnetz, dedizierter Backup-User mit minimalen Rechten, monatliche Restore-Tests und definierte Backup-Retention unter Berücksichtigung der DSGVO.
Fragen zu diesem Thema?
Unsere Experten beraten Sie kostenlos und unverbindlich.
Über den Autor
Geschäftsführender Gesellschafter der AWARE7 GmbH mit langjähriger Expertise in Informationssicherheit, Penetrationstesting und IT-Risikomanagement. Absolvent des Masterstudiengangs Internet-Sicherheit an der Westfälischen Hochschule (if(is), Prof. Norbert Pohlmann). Bestseller-Autor im Wiley-VCH Verlag und Lehrbeauftragter der ASW-Akademie. Einschätzungen zu Cybersecurity und digitaler Souveränität erschienen u.a. in Welt am Sonntag, WDR, Deutschlandfunk und Handelsblatt.
10 Publikationen
- Einsatz von elektronischer Verschlüsselung - Hemmnisse für die Wirtschaft (2018)
- Kompass IT-Verschlüsselung - Orientierungshilfen für KMU (2018)
- IT Security Day 2025 - Live Hacking: KI in der Cybersicherheit (2025)
- Live Hacking - Credential Stuffing: Finanzrisiken jenseits Ransomware (2025)
- Keynote: Live Hacking Show - Ein Blick in die Welt der Cyberkriminalität (2025)
- Analyse von Angriffsflächen bei Shared-Hosting-Anbietern (2024)
- Gänsehaut garantiert: Die schaurigsten Funde aus dem Leben eines Pentesters (2022)
- IT Security Zertifizierungen - CISSP, T.I.S.P. & Co (Live-Webinar) (2023)
- Sicherheitsforum Online-Banking - Live Hacking (2021)
- Nipster im Netz und das Ende der Kreidezeit (2017)