hackatoll
Zur Lernplattform

Wissen › SQL-Injection

SQL-Injection

Angreifer-Eingaben verändern die SQL-Abfrage — bis hin zum Auslesen aller Daten (z. B. be_users).

Injection Schweregrad: Kritisch

SQL-Injection entsteht, wenn Nutzereingaben als Teil eines SQL-Strings interpretiert werden statt als reine Daten. Angreifer verändern so die Abfrage, lesen fremde Tabellen aus (etwa die Backend-Logins in be_users) und können — je nach Konfiguration — auch schreiben.

Wie der Angriff funktioniert

Beispiel

Der Unterschied ist, ob die Eingabe als Daten gebunden oder in den String konkateniert wird:

// verwundbar: Eingabe steckt im SQL-String
$sql = "... WHERE bodytext LIKE '%" . $q . "%'";

// sicher: Parameter-Bindung über den QueryBuilder
$qb->where(
    $qb->expr()->like('bodytext',
        $qb->createNamedParameter('%' . $qb->escapeLikeWildcards($q) . '%'))
);

Mögliche Auswirkungen

◆ In TYPO3 beachten

Worauf du in TYPO3 achten musst

TYPO3 bietet mit Doctrine DBAL (QueryBuilder) und Extbase durchgehend parametrisierbare APIs. SQL-Injection in TYPO3-Projekten entsteht praktisch immer durch rohe String-Konkatenation in eigenem Code.

QueryBuilder + createNamedParameter()

Nutzereingaben IMMER über createNamedParameter() binden, nie in den String konkatenieren. Für LIKE zusätzlich escapeLikeWildcards() verwenden.

$qb = GeneralUtility::makeInstance(ConnectionPool::class)
    ->getQueryBuilderForTable('tt_content');
$qb->select('*')->from('tt_content')
   ->where($qb->expr()->eq('uid',
       $qb->createNamedParameter($uid, \PDO::PARAM_INT)));

Bezeichner nicht aus Nutzereingabe

Spalten-/Tabellennamen lassen sich nicht als Parameter binden. Kommen sie aus Eingaben, strikt gegen eine Allowlist prüfen und mit quoteIdentifier() behandeln — niemals direkt einsetzen.

Extbase ist standardmäßig sicher

Repository-Queries über die QueryInterface-API (equals, in, like …) sind parametrisiert. Gefährlich wird erst ->statement() mit zusammengebautem SQL.

Rohe Statements nur mit Bindung

Wenn executeQuery()/executeStatement() auf dem Connection-Objekt nötig ist, Platzhalter + Parameter-Array verwenden — nie Werte in den SQL-String schreiben.

Least Privilege für den DB-User

Der Datenbank-Benutzer der Installation braucht kein FILE-Privileg und keine Rechte außerhalb des TYPO3-Schemas. Das begrenzt den Schaden einer verbliebenen Lücke (z. B. kein INTO OUTFILE).

Schutzmaßnahmen

Interaktiv üben

In der Lernplattform kannst du diese Schwachstellenklasse an einer echten, isolierten TYPO3-Instanz nachvollziehen:

Weiterlesen

Jetzt interaktiv üben →