Auge: GPC-Arrays auf SQL-Injection etc. prüfen

Beitrag lesen

Hallo

Da ich mir noch nicht ganz sicher bin und bei solchen Fragen lieber ein mal zu oft nachfrage als ein mal zu wenig wollte ich mal fragen, was ich machen muss, um SQL-Injection sowie Angriffe auf das PHP-Script per GPC-Daten zu verhindern?

Arbeite, jenachdem, woher du die Daten erwartest mit den superglbalen Arrays $_POST, $_GET, $_COOKIE, $_SESSION. Damit stellst du erstmal die Quelle klar. Je nachdem, um welche Art von Daten es geht, sind weitere Prüfungen angesagt.

Beispiele:

  • Ein übergebener Wert aus einem <select> eines Formulars _muss_ aus einer fest definierten Menge von Möglichkeiten stammen. Du kannst den Wert also gegen ein Array der Möglichkeiten prüfen.
  
// Der Wert kommt per POST aus dem <select name="obst">  
  
// Das Array mit den moeglichen Werten, mit dem  
// auch das Formular gefuettert werden koennte.  
$select_obst = array("Apfel","Birne","Pflaume");  
  
if (isset($_POST["obst"]) and in_array($_POST["obst"],$select_obst))  
   {  
   // Der uebergebene Wert ist im Array vorhanden, er wird weiterverarbeitet.  
   // Ist er nicht vorhanden wird $_POST["obst"] ignoriert. Man koennte das  
   // Element auch bei Vorhandensein explizit loeschen, so es notwendig ist.  
   }  

  • Ähnliches gilt für (Ganz)Zahlen. Da der übergebene Wert ein String ist, wird aber nicht auf is_int sondern auf is_number geprüft. Das geht übrigens auch mit einem regulären Ausdruck. Muss die Zahl in einem bestimmten Bereich liegen, kann (zusätzlich) wieder die Prüfung gegen ein Array erfolgen.
  
// Wir erwarten die Angabe eines Datums (Tag des Monats)  
  
// Monat und Jahr sind bereits bekannt, somit wissen wir,  
// wieviele Tage der Monat haben kann (wegen Schaltjahr).  
// Monat: Februar, Jahr: 2000  
  
// timestamp fuer den 01.02.2000, 00:00:00  
$validdate = mktime(0,0,0,2,1,2000);  
// Ermitteln der Anzahl der Tage des Monats (29)  
$monatstage = date("t",$validdate);  
// Array mit allen moeglichen Werten (1 bis 29)  
$array_mtage = range(1,$monatstage);  
  
if (isset($_POST["tag"]) and is_number($_POST["tag"]) and in_array($_POST["tag"],$array_mtage))  
   {  
   // $_POST["tag"] existiert, ist numerisch und eine gueltige Angabe.  
   }  

Für solche Dinge kann man sich Standardvorgehensweisen schaffen. Alles, was nicht den Erwartungen entspricht, wird von vornherein verworfen.

Jetzt kommt der freie Text. Der lässt sich nicht so einfach prüfen. Da heißt es, Schadensvermeidung durch Entschärfung.

Reicht da eine Schleife, die am Anfang des Scripts alle GPC-Daten nach " und ' durchsucht und gegenenfalls eine Fehlermeldung ausgibt und das Script abbricht oder kann man noch mit mehr Zeichen Schaden anrichten?

Je nach weiterer Verwendung können auch andere Zeichen als " und ' maskiert werden müssen. So ist z.B. zur Speicherung von Daten mit MySQL mysql_real_escape_string() für die Maskierung zuständig. Die Funktion "weiß am besten", welche Zeichen maskiert werden müssen. Da selbst mit addslashes und eigenen Prüfungen rumzukrepeln, ist Unsinn, wenn es dafür bereits eine fertige Funktion gibt.

Das Escapen aller Zeichen dann, wenn sie gebraucht werden mag zwar teilweise resourcensparender sein, hat aber auch seine Nachteile und ist ein ziemlicher Aufwand, der die Lesbarkeit des PHP-Codes meiner Meinung nach doch sehr beeinträchtigt (auch, wenn es nur ein Funktionsaufruf ist).

Wenn du deine Skripte sicher machen willst, kommst du um diese Funktionsaufrufe nicht herum. Und zwar genau dann, wenn sie erforderlich sind. Meiner Meinung nach stören sie auch die Lesbarkeit nicht, sofern der Quelltext eines Skriptes überhaupt lesbar formatiert ist.

Tschö, Auge

--
Die Musik drückt aus, was nicht gesagt werden kann und worüber es unmöglich ist zu schweigen.
(Victor Hugo)
Veranstaltungsdatenbank Vdb 0.1