flawopen.com/SQL-Injection/Javascript

SQL-Injection in Javascript

Kritisch CWE-89 Draft — pending review
Language: English Português (Brasil) Español Français Deutsch Русский 简体中文 日本語 हिन्दी 한국어 Bahasa Indonesia
Einfach erklärt

Stell dir ein Formular vor, das nur eine Ticketnummer erwartet. SQL-Injection passiert, wenn jemand Code in dieses Feld eingibt, der die Datenbank dazu bringt, alle Daten herauszugeben, weil die Eingabe unbereinigt in den Befehl eingefügt wurde.

Schlüsselbegriffe auf dieser Seite
Template-Literal
Zeichenketten in Backticks (`...`), die Variablen direkt einbetten. Wenn sie für SQL verwendet werden, wirken sie wie unsichere String-Verkettung.
Platzhalter
Spezielle Marker (? oder $1), die der Datenbank signalisieren, dass ein Wert separat übergeben wird.

Was passiert

SQL-Injection tritt auf, wenn benutzergesteuerte Eingaben direkt in eine SQL-Abfrage eingefügt werden. In Node.js ist die Falle besonders tückisch, da Template-Literale syntaktisch elegant aussehen, jedoch identisch mit unsicherer Zeichenkettenverkettung sind.

Auswirkung in der Praxis

2015 erlitt der britische Telekommunikationsanbieter TalkTalk einen Datenschutzvorfall mit über 150.000 betroffenen Kunden durch eine SQL-Injection-Schwachstelle. Die Aufsichtsbehörde verhängte eine Strafe von 400.000 £.

Quelle: UK Information Commissioner's Office, 2016.

Verwundbar vs. behoben

VULNERABLE
// userId comes straight from request query
async function getUser(pool, userId) {
  const query = `SELECT * FROM users
    WHERE id = ${userId}`;
  const [rows] = await pool.query(query);
  return rows[0];
}
FIXED
// value is passed separately, never inlined
async function getUser(pool, userId) {
  const [rows] = await pool.query(
    'SELECT * FROM users WHERE id = ?',
    [userId]
  );
  return rows[0];
}

Warum die Behebung funktioniert

Die behobene Version übergibt die Abfrage und die Parameter als zwei separate Argumente an den Treiber. Die Datenbank kompiliert zuerst die Abfragestruktur, bevor die Werte gebunden werden.

Sprachspezifische Gotchas

Treibersyntax unterscheidet sich

mysql2 verwendet Fragezeichen (?), während pg (PostgreSQL) nummerierte Platzhalter ($1, $2) nutzt. Das Vermischen führt zu Laufzeitfehlern.

Prisma $queryRawUnsafe

Prisma schützt standardmäßig, aber $queryRawUnsafe hebt diesen Schutz vollständig auf.

Häufige Missverständnisse

"Node.js ist asynchron und deshalb sicher"

Asynchronität betrifft nur das I/O-Modell, bietet aber keinerlei Schutz gegen fehlerhafte SQL-Syntaxkonstruktion.

Wie Sie prüfen, ob Sie betroffen sind

grep -rn "query(\`.*\${" --include="*.js" --include="*.ts" . npx eslint --rule 'no-template-curly-in-string: error' .
Run Semgrep with p/javascript ruleset in CI to catch unparameterized database queries automatically.

Präventions-Checkliste

Häufig gestellte Fragen

Schützt TypeORM automatisch?

Ja für den QueryBuilder, aber nicht bei rohen Abfragen mit query() oder where() ohne Parameterbindung.

Referenzen

Siehe auch: Cross-Site Scripting Command InjectionPath Traversal