Sicherheit in PHP Scripten



  • RandomAccess85 schrieb:

    Hallo,

    php_info() aufrufen und schauen ob allow_url_include auf on gesetzt ist! Sollte dies der Fall sein ist die Sicherheitslücke offen. In dem Fall sollte allow_url_include auf off gesetzt werden => php.ini

    Sollte dies aus irgend einem Grund nicht machbar sein, einfach mittels file_exists() prüfen. Soweit ich weiß ist file_exists() Serverübergreifend nicht möglich und gibt somit false zurück...

    if (file_exists($_GET['vulnvar']))
       include($_GET['vulnvar']);
    else
       echo("Error");
    

    LG, Micha

    Guter Vorschlag, gibt aber ein paar kleine haken:
    - aus erfahrung weiß ich das 70% der user nicht an die php.ini rannkommen
    - allow_url_inlude() ist erst ab PHP Version 5.2.0 verfügbar

    Im Falle das der übergebene Parameter eine zu includierende Datei ist, denke ich die meisten sollten es so machen wie du sagst, mittels file_exsist prüfen ob die übergebene datei existiert und gut.



  • RandomAccess85 schrieb:

    Hallo,

    Sollte dies aus irgend einem Grund nicht machbar sein, einfach mittels file_exists() prüfen. Soweit ich weiß ist file_exists() Serverübergreifend nicht möglich und gibt somit false zurück...

    if (file_exists($_GET['vulnvar']))
       include($_GET['vulnvar']);
    else
       echo("Error");
    

    LG, Micha

    stellen wir uns vor, dass ein angreifer ein Bild auf den server upgeloadet hat in dem eigentlich im klartext phpcode steht.
    Ab jetzt wird eine include von einem lokalem file eine Katastrophe bedeuten und file_exists wird uns nicht ausreichen.



  • einfache Lösung:

    http://www.example.com/index.php?include=test

    include( "/includes/" + $_GET['include'] + ".php" );
    


  • Hallo,

    dafür gibt es Funktionen die beim Upload genutzt werden können um zu prüfen ob es sich bei der angegebenen Datei tatsächlich um ein Bild handelt.

    siehe hier

    oder:

    $_FILES['datei']['type'] // gibt ebenfalls der mime-type zurück
    

    Sollte man trotzdem noch Angst vor Angriffen aus dieser Richtung haben, verzichtet man einfach auf diese Art und Weise und[h]schafft sich lieber eine anständige Datenbank und spielt mit den ID's

    LG, Micha



  • für mich scheint der Vorschlag von @zwutz als sicher zu sein, da er wenigstens ein vordefinierter Ordner, wo die erlaubte scripts liegen als auch richtige Erweiterung einbindet.

    Die Upload-Datein müssen natürlich um jeden preis wenigsten auf Type an Hand von Erweiterung untersucht werden zbs viel schlimmer als ein bild mit PHP-Code könnte einfache .htaccess datei sein in der erlaubt wird eine Bilddatei als PHP-Script direkt auszuführen (AddType ....).



  • zwutz schrieb:

    einfache Lösung:

    http://www.example.com/index.php?include=test

    include( "/includes/" + $_GET['include'] + ".php" );
    

    Ja, einfach ... zu umgehen:

    Wenn der String ein Zerobyte enthält, erkennt PHP (mit C als Unterbau) ein angebliches Ende der Zeichenkette. Ist $_GET['include'] = "../pwd\0" , wird das ".php" am Ende abgeschnitten und /pwd inkludiert.

    Grundlegendes Sicherheitsprinzip:
    Arbeite niemals mit Blacklists, sondern immer mit Whitelists.

    key = $_GET['include']
    wl = array( 'index', 'help', 'impressum', 'products', ...)
    if not in array(key, wl) {
     die
    }
    


  • Grundlegendes Sicherheitsprinzip:
    Arbeite niemals mit Blacklists, sondern immer mit Whitelists.

    Mein reden... sagte ich bereits in meinem ersten Beitrag 😉

    Nordin schrieb:

    Fazit:
    IMMER GET und POST prüfen!

    Man sollte sich als jedes mal die Mühe machen und prüfen ob der übergebene Wert auch erlaubt ist bzw. existiert.

    In dem Beispiel von seq wäre es dann so richtig:
    (Es soll zb. die Datei home.php aufgerufen werden.)

    <?php
    if (isset($_GET['vulnvar']) AND $_GET['vulnvar'] == 'home')
        {
        include ('home.php');
        }
    
        else
        {
        echo "kein wert bekommen";
        }
    
    ?>
    

    Aber umm dein Beispiel mal als funktionstüchtigen PHP-Code zu machen:

    $key = $_GET['include'];
    $wl = array( 'index', 'help', 'impressum', 'products');
    if (!in_array($key, $wl)) {
    	die('Seite existiert nicht');
    }
    


  • árn[y]ék schrieb:

    zwutz schrieb:

    einfache Lösung:

    http://www.example.com/index.php?include=test

    include( "/includes/" + $_GET['include'] + ".php" );
    

    Ja, einfach ... zu umgehen:

    ich bin leider nicht stark in "C" (7 Jahren mit PHP beschäftigt) und würde gerne auf eine kleine programm mit quellcode freuen, die diese Aussage testen lässt (sicherheitslücken darf ich auf keinen Fall ignorieren).
    In jedem Fall muss ich das auf dem localhost ansprechen können mit der echter GET-Variable, die \0 über http bekommt.
    Natürlich werde ich dann auch '+' durch '.' ersetzen, um die Richtige verkettung zu bekommen 🙂 .



  • árn[y]ék schrieb:

    zwutz schrieb:

    einfache Lösung:

    http://www.example.com/index.php?include=test

    include( "/includes/" + $_GET['include'] + ".php" );
    

    Ja, einfach ... zu umgehen:

    hab nochmal meinen Code durchgesehen, da das dann doch schon ein weilchen her ist...

    Ich kann dich beruhigen, ich hab vorgesorgt 😉

    zuerst jage ich die Variable durch mysql_real_escape_string und wende sie auf eine whitelist an ^^



  • @slava
    brauchst du jetzt was für C oder PHP?



  • Hmm, seltsam ...

    Ich habe es gerade einmal auf die Schnelle getestet und konnte es tatsächlich nicht rekonstruieren, bin mir aber sicher vor einiger Zeit mal einen ausgiebigeren Artikel über diese Problematik in PHP gelesen zu haben.

    Vielleicht wurde die "Lücke" inzwischen auch geschlossen.

    Ich schaue morgen jedenfalls einmal genauer nach meiner alten Quelle, aber wie es aussieht kann ich dich zumindest momentan doch erst einmal beruhigen, wenn du eine aktuelle PHP-Version einsetzt.

    Nachtrag:
    Also, den Text habe ich gefunden im Buch "PHP-Sicherheit, 2. Auflage" von 2007. Auf meinem System konnte ich die beschriebene Lücke dennoch nicht reproduzieren. Ich gehe also davon aus, dass es diese Möglichkeit zur Parameter Injection in PHP nicht mehr gibt. Sorry, da war mein Wissen wohl etwas angestaubt ...



  • Müsste die darunterliegende Schicht (z.B. Apache?) nicht auch Anfragen mit 0-Bytes verwerfen?



  • Badestrand schrieb:

    Müsste die darunterliegende Schicht (z.B. Apache?) nicht auch Anfragen mit 0-Bytes verwerfen?

    ich weiss nicht ob Apace das verwirft, aber ich kann mir kaum vorstellen, dass PHP auf ein mal zwei strings nicht verketet nur weil in einem \0 steckt.

    @Nordin
    Die Sache ist jetzt erledigt, so lange man kein beweis für die oben beschriebene Sicherheitslücke bekannt ist.

    @árn[y]ék du hast mich echt beruhigt.
    Es tauchen zwar immer wieder die Lücken auf, aber so weit sie bekannt sind, versucht man auch sie zu schließen.

    Danke!



  • SQL:
    PDO benutzen

    Include über GET:
    Einfach noch ein Verzeichnis voransetzen:
    include("content/$_GET["language"]/....php")

    Und fertig. 0 Probleme.



  • DerFollBrofi schrieb:

    SQL:
    PDO benutzen

    Include über GET:
    Einfach noch ein Verzeichnis voransetzen:
    include("content/$_GET["language"]/....php")

    Und fertig. 0 Probleme.

    Das ermöglicht dann aber wiederum, dass evtl. PHP-Dateien aus einem Verzeichnis ausgelesen werden, wo es nicht sein soll. Das Beispiel hatten wir auch schon: In einem Forum lädt beispielsweise jemand eine Datei "blubb.php" hoch, die auch tatsächlich Code enthält. Nun muss er nur noch in $_GET['language'] auf den entsprechenden Pfad verweisen (z.B. "../../uploads/") und schon hast du deine Code Injection.

    Man muss es sich nicht komplizierter machen, als es ist, aber zu einfach dann auch wieder nicht 😉



  • 😃 5 Seiten.... und die besten Antworten stehen auf den ersten beiden Seiten.

    Um es langsam mal abzuschließen:
    Man muss sich gedanken machen "was habe ich vor". Erst nachdem "was habe ich vor" kann ich mir aussuchen für welche variante ich mich entscheide oder es vielleicht mit Dies und Das kombinieren.


Anmelden zum Antworten