flawopen.com/SQL-Injection in Rust/sqlx
Verhindert sqlx-Abfrageprüfung zur Kompilierzeit SQL-Injection?
query! prüft eine literale Abfrage während der Kompilierung anhand des echten Datenbankschemas. Dadurch wird eine dynamisch zusammengesetzte Abfrage nicht nachträglich sicher. Trennen Sie Werte mit gebundenen Parametern vom SQL.
let user_id: String = read_user_input();
let q = format!(
"SELECT id FROM users WHERE id = '{}'",
user_id
);
// Representative only: data and SQL syntax are mixed.
// Never pass user-influenced SQL as AssertSqlSafe.
let user_id: &str = read_user_input();
// PostgreSQL; query! checks the configured schema.
sqlx::query!(
"SELECT id FROM users WHERE id = $1",
user_id
).fetch_one(&pool).await?
Was die Prüfung zur Kompilierzeit tatsächlich validiert
Das SQLx-0.9-Makro query! verlangt ein Zeichenkettenliteral und prüft Syntax, Parametertypen und Ergebnistypen beim Build anhand des konfigurierten Datenbankschemas; dafür müssen DATABASE_URL oder eingecheckte Offline-Metadaten verfügbar sein. Dieses Beispiel gilt für PostgreSQL: Der Platzhalter lautet $1. SQLx empfiehlt $1 für PostgreSQL und SQLite; MySQL und MariaDB verwenden positionale ?-Platzhalter. Die Laufzeitfunktion query() kann Werte mit .bind() binden, wenn die SQL-Struktur fest oder anwendungskontrolliert ist. In SQLx 0.9 müssen dynamische Abfragezeichenketten mit AssertSqlSafe übergeben werden; dieser Typ bestätigt lediglich die Sicherheit und bereinigt die Zeichenkette nicht. Verwenden Sie ihn niemals, um eine Zeichenkette mit interpolierten nicht vertrauenswürdigen Werten freizugeben.
So prüfen Sie Ihre Codebasis
rg -n 'format!\s*\(|sqlx::query(_as)?\s*\(' --glob '*.rs'Häufige Fragen
Verwenden Sie query!, wenn die Anforderungen an Literalabfrage und Build-Schema zum Projekt passen; es ergänzt SQL- und Typprüfungen zur Kompilierzeit. Dynamisches query() ist ebenfalls sicher, wenn jeder Wert mit .bind() gebunden wird. Interpolieren Sie in beiden Fällen niemals nicht vertrauenswürdige Daten in die SQL-Syntax.
Quellen
- flawopen.com — SQL-Injection in Rust
- SQLx-Dokumentation — query!-Makro und Platzhalter je Datenbank
- SQLx-Dokumentation — AssertSqlSafe (Zusicherung, keine Bereinigung)