DuckDB absichern
DuckDB ist eine leistungsfähige analytische Datenbank-Engine. Sie kann Dateien lesen und schreiben, auf das Netzwerk zugreifen, Erweiterungen laden und Systemressourcen nutzen. Wie bei jedem leistungsfähigen Werkzeug erfordern diese Fähigkeiten eine angemessene Konfiguration, wenn Sie mit sensiblen Daten oder in gemeinsam genutzten Umgebungen arbeiten.
Diese Seite beschreibt DuckDBs Sicherheitsmodell und sicherheitsrelevante Einstellungen. Die richtige Konfiguration hängt von Ihrem Anwendungsfall, Ihrer Umgebung und Ihrem Bedrohungsmodell ab. Wenn Sie DuckDB in Ihre Anwendung einbetten möchten, lesen Sie auch die Seite „DuckDB einbetten“.
Nicht vertrauenswürdige Eingaben
Nicht vertrauenswürdige SQL-Eingaben
Warnung Behandeln Sie SQL in DuckDB wie Code in Bash oder Python. Führen Sie SQL aus nicht vertrauenswürdigen Quellen nicht ohne geeignetes Sandboxing aus.
DuckDB führt SQL mit den vollen Rechten des ausführenden Benutzers aus, ähnlich einer Shell oder eines Skriptinterpreters (etwa bash oder Python). So wie Sie ein nicht vertrauenswürdiges Shell-Skript oder Python-Programm nicht ohne Sandboxing ausführen würden, sollten Sie bei SQL in DuckDB dieselbe Vorsicht walten lassen.
Wenn Ihre Anwendung SQL aus nicht vertrauenswürdigen Quellen ausführen muss, nutzen Sie zusätzliche Schutzmaßnahmen wie bei nicht vertrauenswürdigem Code, zum Beispiel:
- duckdb-wasm zum Sandboxing
- DuckDB in einem isolierten Container ausführen (z. B. Docker mit eingeschränkten Capabilities)
- Eine virtuelle Maschine oder einen separaten Prozess mit minimalen Rechten nutzen
- Sandboxing auf Betriebssystemebene anwenden
- Netzwerkisolation, um Datenexfiltration zu verhindern
- Strikte Query-Timeouts auf Anwendungsebene implementieren
Die auf dieser Seite beschriebenen Einstellungen bieten Defense-in-Depth und können bestimmte Fähigkeiten einschränken, ersetzen aber kein geeignetes Sandboxing. Beachten Sie außerdem, dass Sandboxing nicht nur aus Sicherheitsgründen sinnvoll ist, sondern auch, um Denial-of-Service-(DoS-)Angriffe zu verhindern: Bösartige Eingaben können DuckDB leicht dazu bringen, übermäßig viele Ressourcen wie Speicher, Festplatte, CPU oder Netzwerk zu verbrauchen.
Nicht vertrauenswürdige Nicht-SQL-Eingaben
Warnung Auch Nicht-SQL-Eingaben in DuckDB können leicht unbeabsichtigte Folgen haben. Wenn Sie sicherheitskritische Anwendungen mit DuckDB bauen, müssen Sie die Auswirkungen nicht vertrauenswürdiger Eingaben in DuckDB genau verstehen.
Neben SQL bietet DuckDB mehrere Nicht-SQL-APIs zur Interaktion mit der Datenbank. In Python gibt es beispielsweise eine relationale API, mit der sich Abfragen programmatisch aufbauen lassen.
Diese APIs akzeptieren Benutzereingaben wie Dateipfade, Tabellennamen, Spaltennamen und Filterausdrücke. Sie führen keine rohen SQL-Zeichenketten aus, lösen aber dennoch DuckDB-Operationen aus, die Dateien lesen, auf das Netzwerk zugreifen und Systemressourcen nutzen können.
Beispielhafte Überlegungen zu Nicht-SQL-APIs:
- Dateipfade: Funktionen wie
duckdb.read_csv(path)oderduckdb.read_parquet(path)akzeptieren Dateipfade. Ein vom Angreifer gesteuerter Pfad könnte sensible Dateien lesen (z. B./etc/passwd) oder Remote-URLs ansprechen. - Tabellen- und Spaltennamen: Diese sind in der Regel Identifikatoren und kein ausführbarer Code; unbereinigte Eingaben können aber zu unerwartetem Verhalten oder zur Offenlegung von Informationen führen.
- Filterausdrücke: Manche APIs akzeptieren Filterausdrücke, die in DuckDB-Ausdrücke kompiliert werden und oft Unterabfragen mit beliebigem SQL unterstützen. Behandeln Sie diese mit derselben Vorsicht wie SQL.
Empfehlungen:
- Validieren und bereinigen Sie alle vom Benutzer gelieferten Eingaben, bevor Sie sie an DuckDB-APIs übergeben.
- Wenden Sie dieselben Sandboxing-Prinzipien wie bei nicht vertrauenswürdigem SQL an, wenn Sie Eingaben aus nicht vertrauenswürdigen Quellen akzeptieren.
- Lesen Sie die Dokumentation aller verwendeten Funktionen sorgfältig, um zu verstehen, ob eine Funktion in Ihrem konkreten Anwendungsfall mit nicht vertrauenswürdigen Eingaben sicher ist.
Erweiterungen
DuckDB hat einen flexiblen Erweiterungsmechanismus, der Funktionen wie neue Dateiformate, Funktionen und Remote-Dateisystemzugriff hinzufügt. Erweiterungen laufen mit denselben Rechten wie der DuckDB-Prozess selbst und verdienen daher in sicherheitskritischen Umgebungen besondere Aufmerksamkeit.
Automatisches Laden
DuckDB kann Kern-Erweiterungen automatisch laden, wenn bestimmte SQL-Anweisungen sie benötigen. Um die volle Kontrolle darüber zu behalten, welche Erweiterungen geladen werden, können Sie das automatische Laden deaktivieren:
SET autoload_known_extensions = false;SET autoinstall_known_extensions = false;Kern- vs. Community-Erweiterungen
DuckDB-Erweiterungen fallen in zwei Kategorien:
- Kern-Erweiterungen: Werden vom DuckDB-Team gepflegt und vollständig unterstützt. Dazu gehören Erweiterungen wie
parquet,jsonundhttpfs. - Community-Erweiterungen: Werden von Dritten beigesteuert und über
INSTALL extension_name FROM communityinstalliert. Sie werden nicht vom DuckDB-Team gepflegt; installieren Sie Community-Erweiterungen daher nur aus Quellen, denen Sie vertrauen.
Um Community-Erweiterungen vollständig zu deaktivieren:
SET allow_community_extensions = false;Schwachstellen melden
Wenn Sie eine mögliche Schwachstelle entdecken, melden Sie sie vertraulich über GitHub.
Einstellungen zur Einschränkung der DuckDB-Funktionen
Die in diesem Abschnitt dokumentierten Einstellungen bieten zusätzliche Härtung für DuckDB-Deployments. Sie sollten jedoch nicht in allen Konfigurationen als umfassende Sicherheitsmechanismen verstanden werden. Diese Einstellungen sind als Defense-in-Depth-Maßnahmen gedacht, um die Auswirkungen möglicher Sicherheitsprobleme zu begrenzen. Sie können keinen vollständigen Schutz gegen alle Angriffsvektoren bieten, insbesondere beim Ausführen von nicht vertrauenswürdigem SQL. Für robuste Sicherheit bei nicht vertrauenswürdigen Eingaben kombinieren Sie diese Einstellungen mit geeignetem Sandboxing auf Betriebssystem- oder Containerebene, wie im Abschnitt „Nicht vertrauenswürdige SQL-Eingaben“ beschrieben.
Safe Mode (CLI)
Der CLI-Client von DuckDB unterstützt den „Safe Mode“, der DuckDB den Zugriff auf externe Dateien außer der Datenbankdatei untersagt. Er lässt sich über ein Kommandozeilenargument oder einen Dot-Befehl aktivieren:
duckdb -safe ....safe_modeDateizugriff einschränken
DuckDB kann Verzeichnisse auflisten und beliebige Dateien über die read_csv-Funktion des CSV-Parsers lesen oder Text über die read_text-Funktion einlesen.
Dadurch ist das Lesen aus dem lokalen Dateisystem möglich, zum Beispiel:
SELECT *FROM read_csv('/etc/passwd', sep = ':');Dateizugriff deaktivieren
Dateizugriff lässt sich auf zwei Arten deaktivieren. Erstens können Sie einzelne Dateisysteme deaktivieren. Zum Beispiel:
SET disabled_filesystems = 'LocalFileSystem';Zweitens können Sie den externen Zugriff vollständig deaktivieren, indem Sie die Option enable_external_access auf false setzen.
SET enable_external_access = false;Diese Einstellung bedeutet:
ATTACHkann keine Datenbank in einer Datei anhängen.COPYkann nicht aus Dateien lesen oder in Dateien schreiben.- Funktionen wie
read_csv,read_parquet,read_jsonusw. können nicht aus einer externen Quelle lesen.
Die Optionen allowed_directories und allowed_paths
Sie können DuckDBs Zugriff auf bestimmte Verzeichnisse oder Dateien mit den Optionen allowed_directories bzw. allowed_paths einschränken.
Diese Optionen ermöglichen eine feingranulare Zugriffskontrolle für das Dateisystem.
Sie können DuckDB beispielsweise so setzen, dass nur das Verzeichnis /tmp genutzt wird.
SET allowed_directories = ['/tmp'];SET enable_external_access = false;FROM read_csv('test.csv');Mit dieser Einstellung verweigert DuckDB das Lesen von Dateien im aktuellen Arbeitsverzeichnis:
Permission Error:Cannot access file "test.csv" - file system operations are disabled by configurationKonfigurationen sperren
Sicherheitsrelevante Konfigurationseinstellungen sperren sich in der Regel aus Sicherheitsgründen selbst. Wir können beispielsweise Community-Erweiterungen mit SET allow_community_extensions = false deaktivieren, sie aber danach nicht wieder aktivieren, ohne die Datenbank neu zu starten. Der Versuch führt zu einem Fehler:
Invalid Input Error:Cannot upgrade allow_community_extensions setting while database is runningSo wird verhindert, dass explizit deaktivierte Einstellungen wieder aktiviert werden.
Viele Konfigurationseinstellungen sperren sich jedoch nicht selbst, etwa Ressourcenbeschränkungen. Wenn Sie Benutzer unbeschränkt SQL auf Ihrer Hardware ausführen lassen, sollten Sie die Konfiguration nach Abschluss Ihrer eigenen Einstellungen mit folgendem Befehl sperren:
SET lock_configuration = true;Ab diesem Zeitpunkt können keine Konfigurationseinstellungen mehr geändert werden.
Damit bestimmte Einstellungen auch bei aktiviertem lock_configuration konfigurierbar bleiben, nutzen Sie die Option allowed_configs:
SET allowed_configs = ['memory_limit', 'threads'];SET lock_configuration = true;Mit dieser Konfiguration können memory_limit und threads weiterhin geändert werden, alle anderen Einstellungen sind gesperrt.
Secrets
Secrets verwalten Anmeldedaten für Drittanbieterdienste wie AWS oder Azure. DuckDB kann eine Liste der Secrets mit der Tabellenfunktion duckdb_secrets() anzeigen. Sensible Informationen wie Sicherheitsschlüssel werden dabei standardmäßig geschwärzt. Die Option allow_unredacted_secrets kann gesetzt werden, um alle in einem Sicherheitsschlüssel enthaltenen Informationen anzuzeigen. Es wird empfohlen, diese Option nicht zu aktivieren, wenn Sie nicht vertrauenswürdiges SQL ausführen.
Abfragen können auf die im Secrets Manager definierten Secrets zugreifen. Ist beispielsweise ein Secret definiert, das einen Benutzer authentifiziert, der Schreibrechte auf einen bestimmten AWS-S3-Bucket hat, können Abfragen in diesen Bucket schreiben. Das gilt sowohl für persistente als auch für temporäre Secrets.
Persistente Secrets werden unverschlüsselt im Binärformat auf der Festplatte gespeichert. Sie haben dieselben Berechtigungen wie SSH-Schlüssel, 600, d. h. nur der Benutzer, der den DuckDB-(Eltern-)Prozess ausführt, kann sie lesen und schreiben.
Prepared Statements gegen SQL-Injection
Wie bei anderen SQL-Datenbanken wird empfohlen, in DuckDB Prepared Statements zu verwenden, um SQL-Injection zu verhindern.
Wichtig Prepared Statements schützen vor SQL-Injection, wenn Sie die Abfragestruktur kontrollieren, aber nicht vertrauenswürdige Datenwerte akzeptieren (z. B. vom Benutzer gelieferte Suchbegriffe oder IDs). Können Benutzer die SQL-Abfrage selbst liefern, entspricht das der Erlaubnis, beliebigen Code auszuführen – siehe „Nicht vertrauenswürdige SQL-Eingaben“.
Vermeiden Sie daher das Konkatenieren von Zeichenketten für Abfragen:
import duckdbduckdb.execute("SELECT * FROM (VALUES (32, 'a'), (42, 'b')) t(x) WHERE x = " + str(42)).fetchall()Nutzen Sie stattdessen Prepared Statements:
import duckdbduckdb.execute("SELECT * FROM (VALUES (32, 'a'), (42, 'b')) t(x) WHERE x = ?", [42]).fetchall()Ressourcennutzung begrenzen
DuckDB kann beträchtlich viel CPU, RAM und Festplattenspeicher nutzen. Diese Ressourcen lassen sich begrenzen, um die Nutzung der DuckDB-Instanz zu steuern.
Die Anzahl der CPU-Threads, die DuckDB nutzen darf, setzen Sie beispielsweise so:
SET threads = 4;Dabei ist 4 die Anzahl der erlaubten Threads.
Auch der maximale Speicher (RAM) lässt sich begrenzen, zum Beispiel:
SET memory_limit = '4GB';Die Größe des temporären Dateiverzeichnisses begrenzen Sie mit:
SET max_temp_directory_size = '4GB';Berechtigungen
Führen Sie DuckDB nicht als Root-Benutzer aus (z. B. mit sudo).
Es gibt keinen guten Grund, DuckDB als Root auszuführen.