
SQL-Injection in PyAthena über DefaultParameterFormatter (CVE-2026-65321)
Schweregrad: Kritisch, CVSS v4.0 9.3 / CVSS v3.1 9.8 (vergeben von VulnCheck, der CNA)
Vektor (v4.0): CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
Vektor (v3.1): CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Betroffen: PyAthena <= 3.35.3 (alle Versionen bis einschließlich 3.35.3)
Behoben in: 3.35.4
CWE: CWE-89 (Unsachgemäße Neutralisierung spezieller Elemente in einem SQL-Befehl, 'SQL-Injection')
Gemeldet von: Rahul Karne
CNA: VulnCheck
Veröffentlicht: 3. August 2026
PyAthena hat nicht vertrauenswürdige Eingaben in SELECT-Abfragen korrekt und in DELETE-Abfragen inkorrekt escaped.
PyAthena, der weit verbreitete Python-DB-API-Client für Amazon Athena, wählt seine String-Escaping-Routine anhand des führenden Schlüsselworts der Anweisung aus. Anweisungen, die mit SELECT, WITH, INSERT, UPDATE oder MERGE beginnen, erhalten Trino-korrektes Escaping, bei dem ein einfaches Anführungszeichen durch Verdopplung ('') neutralisiert wird. Jede andere Anweisung – meist ein DELETE oder ein CREATE TABLE … AS SELECT (CTAS) – fällt auf Hive-artiges Backslash-Escaping (\') zurück. Die Engine von Athena ist Trino, das einen Backslash innerhalb einer in einfache Anführungszeichen gesetzten Zeichenkette als gewöhnliches Zeichen behandelt; Backslash-Escaping neutralisiert folglich nichts. Ein Angreifer, der einen String-Parameter in einer solchen Anweisung beeinflussen kann, kann das Literal beenden und beliebiges SQL injizieren – ohne Authentifizierung und ohne Benutzerinteraktion.
Der Fehler fehlt daher im Lesepfad und ist genau in den destruktiven Anweisungstypen vorhanden, wo er den größten Schaden anrichtet. Das Paket wird 22,3 Millionen Mal pro Monat heruntergeladen.
PyAthena ist eine Community-Client-Bibliothek von Drittanbietern für Amazon Athena. Es ist kein AWS-Produkt, und dies ist keine Schwachstelle in AWS oder in Athena selbst.
Ein Angreifer, der einen String-Parameter kontrolliert, der an eine anfällige Anweisung übergeben wird, kann aus dem beabsichtigten String-Literal ausbrechen und die Logik der Anweisung verändern. Die direkteste und am zuverlässigsten demonstrierbare Auswirkung ist unbefugtes Löschen von Daten: Ein Payload wie missing' OR 1=1 -- in einer DELETE … WHERE token = %(token)s-Abfrage neutralisiert das WHERE-Prädikat und löscht jede Zeile, die die IAM-Rolle des Athena-Workgroups löschen darf (z. B. alle Zeilen einer Iceberg-Tabelle). Je nach Anweisungstyp und den Berechtigungen der Rolle kann ein Angreifer darüber hinaus über CTAS-Injection vom Angreifer definierte Tabellen erstellen und – sofern er die resultierende Tabelle anschließend lesen kann – Daten aus anderen Tabellen exfiltrieren, auf die die Rolle zugreifen kann.
Alle Auswirkungen sind durch die Berechtigungen des Athena-Workgroups / der IAM-Rolle begrenzt, die der Client verwendet. Es handelt sich um eine Data-Plane-Injection in die SQL-Engine von Athena; sie führt nicht zu Codeausführung auf dem Host, auf dem PyAthena läuft, und auch nicht zur Kompromittierung von AWS selbst.
Wer betroffen ist: Anwendungen, die PyAthena < 3.35.4 mit dem standardmäßigen DefaultParameterFormatter (clientseitige pyformat- / named-Parametersubstitution) verwenden und (1) eine Anweisung erstellen, die nicht mit SELECT/WITH/INSERT/UPDATE/MERGE beginnt – in der Praxis DELETE, CTAS, CREATE VIEW, DROP oder ALTER – und (2) vom Angreifer beeinflusste Daten als String-Parameter an diese Anweisung übergeben.
Wer nicht betroffen ist:
3.35.4 oder neuer verwendet.SELECT/WITH/INSERT/UPDATE/MERGE beginnen; diese werden zum sicheren Escaper mit Anführungszeichen-Verdopplung geleitet.| Metrik | Wert | Quelle |
|---|---|---|
| Downloads, insgesamt | 740,6 Mio. | pepy.tech/projects/pyathena |
| Downloads, letzte 30 Tage | 22,3 Mio. | pepy.tech |
| Downloads, letzte 24 Stunden | 221,0K | pepy.tech |
| Anhaltende Installationsrate | 8,95/Sekunde | pepy.tech |
| Nennenswerte Downstream-Projekte | dbt-athena importiert _escape_hive und _escape_presto direkt aus pyathena.formatter | connections_legacy.py#L23-L27 |
DefaultParameterFormatter.format() wählt die String-Escaping-Funktion ausschließlich anhand des führenden Schlüsselworts der Anweisung aus. Nur eine Allowlist von Präfixen erhält den Trino-korrekten Escaper; jede andere Anweisung fällt auf Hive-artiges Backslash-Escaping zurück.
# src/pyathena/formatter.py, DefaultParameterFormatter.format(), lines ~271-275 (v3.35.2)
operation_upper = operation.upper()
if operation_upper.startswith(("SELECT", "WITH", "INSERT", "UPDATE", "MERGE")):
escaper = _escape_presto # safe: doubles single quotes
else:
escaper = _escape_hive # UNSAFE for Trino: backslash-escapes quotes
# src/pyathena/formatter.py, lines ~157-165 (v3.35.2)
def _escape_hive(val: str) -> str:
escaped = (
val.replace("\\", "\\\\")
.replace("'", "\\'") # produces \' (not a quote escape in Trino)
.replace("\r", "\\r")
.replace("\n", "\\n")
.replace("\t", "\\t")
)
return f"'{escaped}'"
Die SQL-Engine von Amazon Athena ist Trino (in früheren Engine-Versionen Presto). In Trino ist der einzige Escape für ein einfaches Anführungszeichen innerhalb eines in einfache Anführungszeichen gesetzten String-Literals die Verdopplung (''); ein Backslash ist ein literales Zeichen. _escape_hive neutralisiert daher für Athena überhaupt kein Anführungszeichen – es erzeugt ... = 'missing\' OR 1=1 -- ', was Trino als das String-Literal 'missing\' gefolgt von OR 1=1 -- ' parst, also als vom Angreifer kontrolliertes SQL.
Das Design fällt im Fehlerfall gefährlich aus (fail-dangerous): Es führt den sicheren Pfad auf einer Allowlist und setzt für alles andere standardmäßig den unsicheren Escaper ein. Der Upstream-Fix kehrt dies in fail-safe um (standardmäßig den Trino-Escaper verwenden; Hive-Escaping nur für echte Hive-DDL wie CREATE DATABASE/DROP TABLE/MSCK REPAIR, während CTAS und CREATE VIEW als Trino behandelt werden) und entfernt zusätzlich führende SQL-Kommentare, damit ein /* … */ DELETE …-Präfix die Erkennung des Anweisungstyps nicht aushebeln kann.
_escape_hive vermisst keine Sanitisierung – es ist Sanitisierung. Es ist eine korrekte, wohlgeformte Escaping-Routine für die String-Literal-Grammatik von Hive, angewendet auf eine Engine, die Trinos Grammatik verwendet. Taint-Tracking-Werkzeuge modellieren SQL-Injection als nicht vertrauenswürdige Daten, die eine Senke erreichen, ohne durch einen Escaper zu laufen; hier durchlaufen die Daten auf jedem Pfad einen Escaper, und der Escaper sieht exakt wie Remediation-Code aus, weil er Remediation-Code ist – nur für den falschen Dialekt.