FlawOpen

flawopen.com/SQL Injection/Reicht Escaping?

Verhindert Escaping von Anführungszeichen SQL Injection?

CWE-89: SQL InjectionReference page
Kurzantwort

Meistens nicht. Eine Escaping-Funktion hängt von Datenbank, Verbindungszeichensatz, SQL-Modus und dem genauen Anführungs-Kontext ab. Parametrisierte Abfragen halten Werte über die Treiber-API aus der SQL-Syntax heraus. Werte werden gebunden; dynamische Bezeichner, die nicht gebunden werden können, müssen aus einer anwendungseigenen Allowlist stammen.

Warum Escaping in der Praxis fragil ist

Der Verbindungszeichensatz beeinflusst Escaping

Escaping ist kein kontextfreies Ersetzen von Text. MySQL dokumentiert, dass mysql_real_escape_string() den Verbindungszeichensatz nutzt und SET NAMES den Zustand der Clientbibliothek, den diese Funktion verwendet, nicht aktualisiert. Eine Abweichung kann Annahmen über escapten Text ungültig machen. Bevorzugen Sie parametrisierte APIs. Falls Altcode noch Escaping benötigt, verwenden Sie die unterstützte Treiberfunktion mit korrekt konfiguriertem Zeichensatz und behandeln Sie Fehler.

Ein vergessener Aufruf schwächt die gesamte Abwehr

Escaping muss an jeder Interpolationsstelle mit passendem Treiber, Zeichensatz, SQL-Modus und Literal-Kontext korrekt angewendet werden. Parametrisierte APIs machen die Trennung zwischen Wert und Daten an der Abfrage sichtbar und vermeiden manuell zusammengesetzte Literale.

Anführungszeichen decken nicht alle SQL-Kontexte ab

Escaping von Anführungszeichen betrifft nur Zeichen in einem bestimmten Stringliteral. Es erstellt keine sicheren Tabellen- oder Spaltennamen, Schlüsselwörter oder Sortierrichtungen und schützt keine Eingabe in ungequoteten numerischen Ausdrücken. Binden Sie Werte und wählen Sie dynamische SQL-Struktur aus festen Anwendungsoptionen.

VULNERABLE
// Benutzereingabe wird in SQL-Syntax eingefügt
query = f"SELECT id FROM users WHERE name = '{name}'"
cursor.execute(query)
HARDENED
// Der Treiber bindet name als Datenwert
cursor.execute(
    "SELECT id FROM users WHERE name = ?",
    (name,),
)

Was Parameterbindung anders macht

Eine parametrisierte Abfrage übergibt SQL-Struktur und Werte über die Datenbank-API als getrennte Eingaben. Treiber können native Prepared Statements oder eine andere sichere Implementierung nutzen; nehmen Sie keinen bestimmten Ablauf auf Protokollebene an. Entscheidend ist, dass der Wert als Daten und nicht erneut als SQL-Syntax behandelt wird. Verwenden Sie bei Python DB-API den Platzhalter des Treibers und übergeben Sie Werte separat; formatieren Sie die Abfrage nicht als String.

Engineering-Checkliste

Häufige Fragen

Kann Escaping noch das richtige Werkzeug sein?

Für Bezeichner oder SQL-Fragmente, die nicht gebunden werden können, nutzen Sie nur eine vom Treiber unterstützte Quote-API zusammen mit einer festen Allowlist der Anwendung. Escapen Sie keine beliebigen Werte mit einer allgemeinen Funktion.

Ist eine gepflegte Escaping-Funktion des Treibers sicher?

Sie kann im dokumentierten Kontext helfen, hängt aber weiterhin von Datenbank, Verbindungseinstellungen, Quote-Kontext und korrekter Anwendung an jeder Stelle ab. Parametrisierte Abfragen sind für Werte die sicherere Standardeinstellung.

Referenzen

Siehe auch SQL-Injection (CWE-89): Funktionsweise und Schutz in jeder Sprache — flawopen.com Reicht ein ORM aus, um SQL-Injection zu verhindern? Ist Knex.js vor SQL-Injection geschützt? MyBatis ${} vs. #{}: SQL Injection verhindern MySQLi vs. PDO: sichere Prepared Statements Schützt NHibernate vor SQL-Injection? MongoDB NoSQL Injection: sichere Abfragefilter