SQL-Injection

Viele Webentwickler sind sich nicht bewusst, wie SQL-Abfragen manipuliert werden können und gehen davon aus, dass eine SQL-Abfrage ein vertrauenswürdiges Kommando ist. Das heißt, dass SQL-Abfragen in der Lage sind, Zugriffskontrollen und dadurch Standard-Authentifizierungs- und Autorisierungsprüfungen zu umgehen, und manchmal können SQL-Abfragen sogar Zugriff zu Kommandos auf Betriebssystemebene erlauben.

Direct SQL Command Injection ist eine Technik, wo ein Angreifer SQL-Kommandos erstellt oder existierende verändert, um versteckte Daten sichtbar zu machen, wertvolle Daten zu überschreiben oder sogar gefährliche Kommandos auf Systemebene des Datenbank-Hosts auszuführen. Dies wird durch die Anwendung erreicht, welche den Input des Benutzers mit statischen Parametern kombiniert, um eine SQL-Abfrage zu erstellen. Die folgenden Beispiele basieren - leider - auf wahren Begebenheiten.

Aufgrund der fehlenden Eingabevalidierung und dem Verbinden zum Datenbankserver als ein Superuser oder jemand, der Benutzer anlegen kann, kann ein Angreifer einen Superuser in Ihrer Datenbank anlegen.

Beispiel #1 Die Ergebnisliste in mehrere Seiten aufsplitten ... und Superuser anlegen (PostgreSQL)

<?php

$offset 
$argv[0]; // Vorsicht, keine Validierung der Eingabe!
$query  "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset;";
$result pg_query($conn$query);

?>
Normale Benutzer klicken auf die 'nächste'- bzw. 'vorige'-Links, wo der $offset in der URL enthalten ist. Das Skript erwartet, dass der ankommende $offset einen Dezimalwert enthält. Was aber, wenn jemand versucht einzubrechen, indem er das folgende in einer urlencode()'d Form an die URL anhängt:
0;
insert into pg_shadow(usename,usesysid,usesuper,usecatupd,passwd)
    select 'crack', usesysid, 't','t','crack'
    from pg_shadow where usename='postgres';
--
In diesem Fall würde ihm das Skript einen Superuser-Zugang zur Verfügung stellen. Beachten Sie, dass 0; einen gültigen Offset zur ursprünglichen Abfrage liefert, und sie beendet.

Hinweis:

Es ist eine übliche Technik, den SQL-Parser mit dem SQL-Kommentarzeichen -- zu zwingen, den Rest der vom Entwickler geschriebenen Abfrage zu ignorieren.

Eine gangbare Methode, an Passwörter zu gelangen, ist, Ihre Seiten mit den Suchergebnissen zu umgehen. Der Angreifer braucht nur zu probieren, ob irgendeine übertragene Variable, die in dem SQL-Statement verwendet wird, nicht richtig gehandhabt wird. Diese Filter können gewöhnlich in einem vorausgehenden Formular gesetzt werden, indem WHERE-, ORDER BY-, LIMIT- und OFFSET-Klauseln in SELECT-Statements angepasst werden. Wenn Ihre Datenbank das UNION-Konstrukt unterstützt, kann der Angreifer versuchen, eine komplette Abfrage an das Original anzuhängen, um Passwörter aus einer beliebigen Tabelle aufzulisten. Die Verwendung von verschlüsselten Passwortfeldern wird ausdrücklich empfohlen.

Beispiel #2 Artikel auflisten ... und ein paar Passwörter (beliebiger Datenbankserver)

<?php

$query  
"SELECT id, name, inserted, size FROM products
           WHERE size = '
$size'";
$result odbc_exec($conn$query);

?>
Der statische Teil der Abfrage kann mit einem anderen SELECT-Statement kombiniert werden, welches alle Passwörter preisgibt
'
union select '1', concat(uname||'-'||passwd) as name, '1971-01-01', '0' from usertable;
--
Wenn diese Abfrage (mit dem ' und --) einer der in $query verwendeten Variablen zugewiesen würde, wird das Abfrage-Biest erwachen.

Auch SQL-UPDATEs sind anfällig für Angriffe. Diese Abfragen sind ebenfalls durch das Ändern und Anhängen einer komplett neuen Abfrage gefährdet. Aber der Angreifer könnte auch mit der SET-Klausel herumspielen. In diesem Fall muss eine Schemainformation vorhanden sein, um die Abfrage erfolgreich manipulieren zu können. Diese kann durch Untersuchen der Variablennamen im Formular, oder simpel mittels Brute-Forcing gesammelt werden. Es gibt nicht so viele Namenskonventionen für Felder, welche Passwörter oder Benutzernamen speichern.

Beispiel #3 Vom Zurücksetzen eines Passworts ... zum Erlangen von mehr Rechten (beliebiger Datenbankserver)

<?php
$query 
"UPDATE usertable SET pwd='$pwd' WHERE uid='$uid';";
?>
Aber wenn ein böswilliger Benutzer den Wert ' or uid like'%admin% an $uid übermittelt, um das Administrator-Passwort zu ändern, oder einfach $pwd auf hehehe', trusted=100, admin='yes setzt, um mehr Rechte zu erhalten, dann wird die Abfrage verdreht:
<?php

// $uid: ' or uid like '%admin%
$query "UPDATE usertable SET pwd='...' WHERE uid='' or uid like '%admin%';";

// $pwd: hehehe', trusted=100, admin='yes
$query "UPDATE usertable SET pwd='hehehe', trusted=100, admin='yes' WHERE
...;"
;

?>

Ein erschreckendes Beispiel, wie der Zugriff auf Befehle auf Betriebssystemebene bei manchen Datenbankservern erfolgen kann:

Beispiel #4 Angriff auf das Betriebssystem des Datenbank-Hosts (MSSQL-Server)

<?php

$query  
"SELECT * FROM products WHERE id LIKE '%$prod%'";
$result mssql_query($query);

?>
Wenn ein Angreifer den Wert a%' exec master..xp_cmdshell 'net user test testpass /ADD' -- auf $prod überträgt, wird $query zu:
<?php

$query  
"SELECT * FROM products
           WHERE id LIKE '%a%'
           exec master..xp_cmdshell 'net user test testpass /ADD' --%'"
;
$result mssql_query($query);

?>
Der MSSQL-Server führt die SQL-Statements im Batch aus, inklusive eines Kommandos um einen neuen Benutzer zur Datenbank der lokalen Konten hinzuzufügen. Würde diese Anwendung als sa und der MSSQLSERVER-Service mit genügend Rechten laufen, hätte der Angreifer nun ein Konto, mit welchem er Zugriff auf diese Maschine hätte.

Hinweis:

Manche der obigen Beispiele sind an einen spezifischen Datenbankserver gebunden. Das heißt jedoch nicht, dass nicht ein ähnlicher Angriff auf andere Produkte möglich wäre. Ihr Datenbankserver könnte auf andere Weise genauso verwundbar sein.

Ein praktisches Beispiel für die Problematik der SQL-Injection
Bild mit freundlicher Genehmigung von » xkcd

Techniken zur Vermeidung

Obwohl es offensichtlich ist, dass ein Angreifer zumindest ein wenig Kenntnis der genutzten Datenbankarchitektur besitzen muss, um einen erfolgreichen Angriff durchzuführen, ist es oft sehr einfach, diese Informationen zu erhalten. Wenn die Datenbank zum Beispiel Teil eines Open-Source- oder eines anderen öffentlich verfügbaren Softwarepakets mit einer Standardinstallation ist, dann sind diese Informationen vollkommen offen und frei zugänglich. Diese Informationen können auch durch Closed-Source-Code preisgegeben werden - selbst wenn dieser kodiert, verschleiert oder kompiliert ist - und sogar durch Ihren ureigenen Code durch die Anzeige von Fehlermeldungen. Andere Methoden beinhalten die Nutzung typischer Tabellen- und Spaltennamen. Ein Login-Formular etwa, dass eine Tabelle 'users' mit den Spaltennamen 'id', 'username' und 'password' nutzt.

Diese Angriffe basieren hauptsächlich auf dem Ausnutzen des Codes, der nicht mit Blick auf die Sicherheit geschrieben wurde. Vertrauen Sie nie auf irgendeine Art von Eingabe, insbesondere wenn sie von der Clientseite kommt, selbst wenn er von einer Auswahlbox, einem versteckten Eingabefeld oder einem Cookie kommt. Das erste Beispiel zeigt, dass solch eine tadellose Abfrage ein Desaster anrichten kann.

  • Stellen Sie nie als Superuser oder Eigentümer einer Datenbank eine Verbindung zur Datenbank her. Verwenden Sie immer speziell angelegte Benutzer mit sehr limitierten Rechten.
  • Verwenden Sie Prepared-Statements mit gebundenden Variablen. Sie werden von PDO, MySQLi und anderen Bibliotheken angeboten.
  • Prüfen Sie, ob die gegebene Eingabe dem erwarteten Datentyp entspricht. PHP bietet eine große Auswahl an Funktionen zum Validieren der Eingaben, von den einfachsten unter Variablenfunktionen und Character-Type-Funktionen (z.B. is_numeric(), bzw. ctype_digit()), bis hin zu den Perl-kompatiblen regulären Ausdrücken.
  • Wenn die Anwendung eine numerische Eingabe erwartet, erwägen Sie die Prüfung der Daten mit ctype_digit() oder die Änderung des Typs mit settype() oder verwenden Sie die numerische Darstellung mittels sprintf().

    Beispiel #5 Ein sicherer Weg, eine Abfrage zu erstellen

    <?php

    settype
    ($offset'integer');
    $query "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset;";

    // Beachten Sie %d im Formatstring, %s zu verwenden wäre sinnlos
    $query sprintf("SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET %d;",
                     
    $offset);

    ?>

  • Unterstützt die Datenbank-Ebene das Binden von Variablen nicht, so maskieren Sie jede nichtnumerische Benutzereingabe, welche zur Datenbank weitergereicht werden soll, mit der jeweiligen datenbankspezifischen Maskierungsfunktion für Zeichenketten (z.B. mysql_real_escape_string(), sqlite_escape_string() usw.). Generische Funktionen wie addslashes() sind nur in einer sehr spezifischen Umgebung nützlich (z.B. MySQL mit einem SingleByte-Zeichensatz bei deaktiviertem NO_BACKSLASH_ESCAPES), so dass es besser ist, diese zu vermeiden.
  • Geben Sie um keinen Preis irgendwelche datenbankspezifischen Informationen aus, speziell über das Schema. Siehe auch Fehlerbehandlung und Fehlerbehandlungsfunktionen.
  • Sie können Stored-Procedures und vorher definierte Cursor verwenden, um den Datenzugriff zu abstrahieren, sodass Benutzer nicht direkt auf Tabellen oder Views zugreifen, aber diese Lösung hat andere Auswirkungen.

Abgesehen davon profitieren Sie von einer Protokollierung der Abfragen entweder in Ihrem Skript oder durch die Datenbank selbst, falls sie Protokollierung unterstützt. Klar, die Protokollierung kann keinen schädlichen Versuch verhindern, aber sie kann helfen herauszufinden, welche Anwendung umgangen wurde. Das Protokoll ist nicht von sich aus nützlich, aber durch die in ihm enthaltenen Informationen, und je mehr Details es enthält, desto besser ist es im Allgemeinen.

Hier Kannst Du einen Kommentar verfassen


Bitte gib mindestens 10 Zeichen ein.
Wird geladen... Bitte warte.
* Pflichtangabe
Es sind noch keine Kommentare vorhanden.

PhpStorm 2022. 3 Update mit PHP 8.3 Unterstützung

PhpStorm 2022. 3 Update mit PHP 8.3 Unterstützung

PhpStorm unterstützt jetzt PHP 8. 2, die neueste Version von PHP. Somit können alle neuen Funktionen genutzt werden, die in der PHP 8. 2 Version eingeführt wurden. ...

admin

Autor : admin
Kategorie: Software-Updates

Was muss ich in WordPress einstellen, damit Google Fonts nicht mehr geladen werden?

Möchten Du WordPress davon abhalten, Google Fonts zu verwenden? Hier erfährst Du, was du dafür in WordPress einstellen musst. ...

admin

Autor : admin
Kategorie: Sonstige Tutorials

Abmahnwelle durch Google Fonts - was ist zu beachten und wie schütze ich mich?

Abmahnwelle durch Google Fonts - was ist zu beachten und wie schütze ich mich?

Eine Abmahnwelle wegen Google Fonts rollt derzeit durch das Land und verunsichert viele Betreiber von Webseiten. Ausschlaggebend hierfür war ein Urteil des Landgerichts München vom 20.01.2022. ...

Bernie

Autor : ebiz-consult GmbH & Co. KG
Kategorie: Dies und Das

Tutorial veröffentlichen

Tutorial veröffentlichen

Teile Dein Wissen mit anderen Entwicklern weltweit

Du bist Profi in deinem Bereich und möchtest dein Wissen teilen, dann melde dich jetzt an und teile es mit unserer PHP-Community

mehr erfahren

Tutorial veröffentlichen

Daten aus Datenbank in ein Modal übergeben per a link

Vielen Dank für die Antwort. Ich habe den Code bei den Abfragen geändert und es macht deutlich mehr Sinn so. Mit Ajax beschäftige ich mich erst ...

Geschrieben von Jens am 09.12.2022 16:33:52
Forum: SQL / Datenbanken
Daten aus Datenbank in ein Modal übergeben per a link

Vielen Dank für die Antwort. Ich habe den Code bei den Abfragen geändert und es macht deutlich mehr Sinn so. Mit Ajax beschäftige ich mich erst ...

Geschrieben von MattOhl am 09.12.2022 15:26:50
Forum: SQL / Datenbanken
Daten aus Datenbank in ein Modal übergeben per a link

Hi! Ich werde nicht ganz schlau aus deinem WHERE-Teil der Datenbankabfragen. Ich hätte etwas in der folgenden Richtung erwartet. Beim Slider: ...

Geschrieben von Jens am 09.12.2022 15:11:34
Forum: SQL / Datenbanken
Erweiterte HTML-Lernempfehlungen

HTML and CSS are relatively 'old' coding languages. However, they are still highly relevant for coders in 2022. Knowledge of HTML and CSS not only ...

Geschrieben von Nivya am 09.12.2022 06:04:33
Forum: HTML, JavaScript, AJAX, jQuery, CSS, Bootstrap, LESS