FlawOpen

flawopen.com/SQL-Injection in Go/GORM Raw SQL und SQL-Injection

Ist GORM Raw() sicher vor SQL-Injection? Parameterbindung in Go

CWE-89: SQL InjectionReferenzseite
Kurzantwort

Stellen Sie sich einen Platzhalter als verschlossenen Umschlag für einen Wert vor: Der Datenbanktreiber sendet den Wert getrennt von den SQL-Anweisungen. GORM Raw() kann ihn sicher binden, wenn der Platzhalter in der Abfrage bleibt und der Wert als Argument übergeben wird. Werden Benutzereingaben in die SQL-Zeichenfolge formatiert, landen Umschlag und Anweisung zusammen und können die Abfrage verändern.

UNSICHER
// Benutzergesteuerter Text wird zu SQL-Syntax
db.Raw(fmt.Sprintf(
  "SELECT * FROM users WHERE id = %s",
  userID,
)).Scan(&user)
SICHER
// Der Treiber bindet userID als Wert
db.Raw(
  "SELECT * FROM users WHERE id = ?",
  userID,
).Scan(&user)

Sicheres GORM Raw SQL und Parameterbindung

GORM und Go-database/sql binden Werte, wenn Platzhalter im SQL bleiben und Argumente separat übergeben werden, etwa db.Where("name = ?", userInput) oder db.Raw("SELECT ... WHERE id = ?", userID). Ein Platzhalter steht für einen Wert, nicht für SQL-Syntax: Tabellen- und Spaltennamen, Sortierrichtung und Operatoren werden durch Wertebindung nicht sicher. Wählen Sie dynamische Bezeichner aus einer festen Allow-List. Methoden wie Order, Select, Table und Raw können angreifbar sein, wenn Benutzereingaben in SQL-Fragmente verkettet werden.

Codebasis durchsuchen

rg -n --glob '*.go' '\.(Raw|Exec|Order|Select|Table)\s*\(' . rg -n --glob '*.go' 'fmt\.(Sprintf|Sprint)' .

FAQ zu GORM Raw SQL und Parameterbindung

Sind GORM-Kettenmethoden immer sicher?

Nein. Bedingungen mit separat übergebenen Werten wie Where("name = ?", input) verwenden Parameterbindung. Verkettete Eingaben in der Bedingung oder rohe SQL-Syntax können weiterhin eine Abfrage einschleusen. Einige Methoden nehmen nicht escapte Bezeichner oder SQL-Fragmente entgegen; prüfen Sie ihre Argumente und erlauben Sie dynamische Struktur nur über Allow-Lists.

Kann ein Platzhalter einen Tabellen- oder Spaltennamen binden?

Nein. Platzhalter stehen für Datenwerte. Für dynamische Bezeichner oder Sortierrichtung wählen Sie feste, anwendungsdefinierte Optionen und fügen nur die validierte Konstante in die SQL-Struktur ein.

Offizielle Quellen und Referenzen

Siehe auch SQL-Injection (CWE-89): Funktionsweise und Schutz in jeder Sprache — flawopen.com Reicht das Escapen von Anführungszeichen gegen SQL Injection? 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?