HomeBlogMagic

REQUESTS absichern gegen SQL-Injections

Es ist sehr gefährlich Daten die man über einen $_GET oder $_POST erhält direkt in einen Datenbank-String einzufügen. Mit ein paar einfachen mitteln lässt sich ein solcher String leicht manipulieren um vollen Zugriff auf die Datenbank zu gelangen. Was dann angerichtet werden kann, könnt ihr euch selber denken.

Auf meiner Seite logge ich versuchte Injections mit, und diese kommen im Minutentakt herein. In meiner früheren Version der Webseite hatte ich jeden einzelnen String den ich an die Datenbank übermittle mit mysqli_real_escape_string abgesichert.
Das Problem daran, man muss penibel darauf achten dass wirklich jede Abfrage abgesichert ist. Und bei der Überarbeitung ist mir aufgefallen dass es Kombinationen gegeben hat wo ich dass dann vergessen hatte. Also war Sicherheit durch Disziplin eher schwer beizubehalten :(.

Mit der neuen Version der Webseite habe ich die Strategie geändert. Die Bedingung ist nun dass es keinen, für die Funktion der Webseite , relevanten String gibt, der von außen hereinkommen darf, um das Verhalten der Datenbank zu beeinflussen.

Kurz gesagt, jeder Input der Datenbank-Befehle oder andere Injections beinhaltet ist von vornherein ungültig.
Deshalb kann ich jeden Wert filtern und absichern.

Ein einfaches Beispiel um in PHP die globale $_GET zu sichern:

$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
$SAVE_GET = array();
foreach($_GET as $key => $value)
{
  $sNewKey   = $mysqli->real_escape_string($key);
  $sNewValue = $mysqli->real_escape_string($value);
  if($key != $sNewKey)
  {
    // injection detected in query-key
  }
  else if($sNewValue != $value)
  {
    // injection detected in query-value
  }
  else
  {
    // secure to use
    $SAVE_GET[$sNewKey] = $sNewValue;
  }
}

Wenn in der restlichen Webseite auf die Verwendung von $_GET verzichtet wird und stattdessen $SAVE_GET eingesetzt wird, ist eine große Sicherheitslücke schon mal dicht.
Die Kommentare können ersetzt werden und eine "Abwehrstrategie" eingesetzt werden.

Diese Art des Vorfilterns der Eingaben wird in meiner gesamten Webseite angewandt, aber man darf nie Vergessen auch weitere Sicherheitsmerkmale zu bedenken!

Erweiterung

Nachdem ich so einige Versuche von SQL-Injections auf meiner Webseite beobachten konnte, musste ich einige meiner SQL-Abfragen nochmal updaten, denn mit dem obigen Code lässt sich eines nicht abfragen, manipulierte bzw. falsche Wert.

Zum Beispiel:

  • Eine normale Abfrage lautet: SELECT * FROM `table` WHERE ID=1
  • Die Abfrage läuft so ohne Probleme durch
  • Erstes update mit einer PHP Variable: SELECT * FROM `table` WHERE ID=$id
  • Solange $id eine gültige Zahl ist, ist es auch kein Problem
  • Sollte aber $id="1; (INJECTION)" heißen, dann können schlimme dinge passieren.

So lässt es sich verhindern: SELECT * FROM `table` WHERE ID='$id' . Des weitern sollte die Variable $id mit real_escape_string der String maskiert werden. Dadurch Schlägt zwar die Anfrage fehl, aber die Datenbank ist sicher.
Zusätzlich können die Variablen zusätzlich auf Gültigkeit geprüft werden, z.B. mit if(is_int($id)).

Damit sollte auch dieser Angriff abgewehrt werden können.

Permalink: https://adirmeier.de/Blog/ID_115
Tags: Blog, $_GET, $_POST, PHP, SQL, Websitevon am 2017-05-13