FlawOpen

flawopen.com/SQL-Injection in Rust/sqlx

Verhindert sqlx-Abfrageprüfung zur Kompilierzeit SQL-Injection?

Referenzseite
Kurzantwort

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.

UNSICHER — Eingabe in SQL einsetzen
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.
SICHER — Wert mit query! binden
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

Sollte ich immer das Makro query! statt query() verwenden?

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

Siehe auch SQL-Injection (CWE-89): Funktionsweise und Schutz in jeder Sprache — flawopen.com Schützen gespeicherte Prozeduren vor SQL-Injection? Ist TypeORM QueryBuilder vor SQL-Injection sicher? Django ORM und SQL Injection: sichere Muster Doctrine ORM: SQL-Injection vermeiden EF Core FromSqlRaw: Sicheres SQL mit Parametern FastAPI SQL Injection: Was Pydantic verhindert