PHP Tutorials, PHP lernen, PHP Forum, PHP Community and more ... MyWebsolution.de!

Sidebar

Home News Tutorials Workshops Tipps Artikel Gästebuch Sitemap Pascal Landau

Suche

Members

Forum Login Registrierung

Statistik

Statistikbereich
Jetzt2
Heute466
Gestern409
Gesamt2393945

SQL Injection

Autor Flitze
Klicks 30861
Bewertungen 18
Rating 6.6
Stand 18.06.2009
Keywords:
SQL Injection, fremden Code einschleusen, Datenbankabfragen schützen, SQL-Queries sichern, mysql_real_escape_string(), addslashes()


Breadcrumb:
Artikel » SQL Injection
Seite : 1 Bewerten
Article Wizard - deutscher Article Spinner

Was ist SQL Injection?

[ADSENSE_LINE]
Mit dieser Art der Injection wird man früher oder später konfrontiert, wenn man SQL-Datenbanken benutzt. Dadurch, dass auch ich eine MySQL-Datenbank verwende, stieß ich auch darauf. SQL-Injection nutzt Sicherheitslücken beim Ausführen eines SQL-Queries aus indem zum Beispiel Funktionszeichen in den Query eingefügt werden. Dadurch kann ein Angreifer eigene SQL-Befehle ausführen, wie z.B. das Ausgeben geschützter Systemdaten oder gar der Veränderung von Benutzerrechten, oder er kann schlichtweg den ursprünglichen SQL-Query manipulieren.

' OR '1' = '1


Zur Verdeutlichung nenne ich ein Beispiel:

Angenommen, es gibt ein Loginfeld, über das sich Benutzer einloggen können. Dazu muss ein Benutzername und ein Passwort eingegeben werden. Da ich davon ausgehe, dass die Daten über ein Formular übergeben werden, stehen sie im Array [var]$_POST[var] zur Verfügung. Eine entsprechende Datenbankabfrage könnte dann so aussehen:

PHP:
<?php
$sql 
"SELECT 
                ID
        FROM
                User
        WHERE
                Benutzername = '"
.$_POST['Benutzername']."' AND
                Passwort = '"
.$_POST['Passwort']."' 
       "
;
$result mysql_query($sql);
?>


Wenn nun ein Angreifer einen auf dem System registrierten Benutzername kennt, kann er sich nun einloggen. Dazu gibt er für den Benutzernamen den Namen des Users ein, in dessen Account er sich einloggen will, z.B. Admin. Als Passwort verwendet er dann folgende Zeichenkette: ' OR '1' = '1

Das würde nun den folgenden Query erzeugen:

PHP:
<?php
$sql 
"SELECT 
                ID
        FROM
                User
        WHERE
                Benutzername = 'Admin' AND
                Passwort = '' OR '1' = '1' 
       "
;
$result mysql_query($sql);
?>


Die Datenbank wird nun nach dem Benutzer Admin durchsucht, dessen Passwort eine leere Zeichenkette ist. Dadurch würde kein Benutzer gefunden werden, indem aber noch ein
OR '1' = '1
angehangen wird, ist das Passwort egal, da die zweite Bedingung des ORs immer erfüllt ist.

Weitere SQL-Befehle anhängen


Es ist jedoch nicht nur möglich, sich in einen anderen Account einzuhacken, sondern man kann auch bedeutet mehr Schaden anrichten, indem man einen zweiten Befehl unterschiebt.

Als Benutzernamen wähle ich wieder Admin, was in diesem Fall jedoch egal ist und für das Passwort benutze ich ; DELETE * FROM User.

Daraus ergibt sich folgender Query:

PHP:
<?php
$sql 
"SELECT 
                ID
        FROM
                User
        WHERE
                Benutzername = 'Admin' AND
                Passwort = ''; DELETE * FROM User 
       "
;
$result mysql_query($sql);
?>


Sofern die Datenbank es zulässt, werden nun alle Datensätze in der Tabelle User gelöscht. Das ist so was wie der Super GAU bei einer Datenbanktabelle.

Auftreten


SQL Injection tritt an jeder Stelle auf, an der ein User Eingaben vornehmen kann, die einen MySQL-Query auslösen. Das sind z.B. Logindaten, Erstellen von Gästebucheinträgen, Erstellen von Forenbeiträgen, Suchanfragen, Anzeigen von Benutzerprofilen (durch die in der URL übergebene ID), etc...

mysql_real_escape_string und das magic_quotes_gpc Problem


Die Injection 'lebt' von den MySQL-Steuerzeichen wie Single Quotes ( ' ), Double Quotes ( " ) und Backslahes ( \ ). Diese Zeichen müssen demnach maskiert werden, so dass sie zwar als 'normale' Zeichen gewertet werden, aber ihre Funktionalität als Steuerzeichen verlieren. Eigentlich sorgt PHP in den meisten Fällen selbständig dafür, dass diese Zeichen maskiert werden. Dazu kann die Einstellung magic_quotes_gpc in der php.ini auf 'on' gestellt werden. Das ist zwar häufig der Fall, hat aber den Nachteil, das es auf jedes '," und \ angewendet wird, selbst wenn sie bereits escaped wurden. Dadurch können x-fach-Escapungen (ich denke mal das Wort gibt es nicht.. aber es lebe der Neologismus :P) entstehen. Aus diesem Grunde ziehe ich es vor, [v]magic_quotes_gpc[/v] zu deaktivieren. Sollte das nicht möglich sein, weil ihr keinen Zugriff auf die php.ini habt, könnt ihr das Ganze 'manuell' außer Kraft setzen. Dazu verwendet man einfach diese Funktion, die ich von #PHP/QuakeNet übernommen habe:

PHP:
<?php
    
// stripslahes für ein mehrdimensionales Array
    
function array_stripslashes(&$variable)
    {
        
// Prüft, ob die Variable ein String ist
        
if (is_string($variable))
            
// Fall ja, wird stripslashes auf diesen String angewandt
            
$variable stripslashes($variable);
        
// Falls nicht, wird geprüft ob sie ein Array ist
        
else {
            
// Ist das der Fall, ruft sich die Funktion rekursiv selbst wieder auf
            
if (is_array($variable)) {
                foreach(
$variable AS $key => $value)
                
array_stripslashes($variable[$key]);
            }
        }
    }
?>


und ruft sie am Anfang des Scriptes folgendermaßen auf:

PHP:
<?php
    
if (get_magic_quotes_gpc()) {
        
array_stripslashes($_POST);
        
// optional auch auf $_GET und $_COOKIE anwenden    
        
array_stripslashes($_GET);
        
array_stripslashes($_COOKIE);
    }
?>


Nachdem magic_quotes_gpc nun von uns außer Kraft gesetzt wurde, sichern wir den Query selbst. Dazu verwenden wir die Funktion addslashes(), oder optimalerweise die Funktion mysql_real_escape_string(), die genau zu diesem Zweck geschaffen wurde. Der korrekte Quellcode eines MySQL-Querys sieht dann so aus:

PHP:
<?php
$sql 
"SELECT 
                ID
        FROM
                User
        WHERE
 Benutzername = '"
.mysql_real_escape_string($_POST['Benutzername'])."' AND
 Passwort = '"
.mysql_real_escape_string($_POST['Passwort'])."'
       "
;
$result mysql_query($sql);
?>


  Bewerten

»» Zurück zum Menu

Suchmaschinenoptimierung

Suchmaschinenoptimierung (SEO - Search Engine Optimization)

Ranking

Tutorials (13)

8.6
8.4
8

Workshops (3)

8.8
8.7
7.6

Tipps (12)

7.2
6.7
6.5

Artikel (32)

8.4
8
7.2

RSS Feeds

Full Feed Tutorials Workshops Tipps Artikel

Twitter

Follow me on Twitter

Partner & Links


Valid HTML 4.01 Transitional
Valid CSS
nach oben

Diese Seiten unterstützen MyWebsolution:
 
© MyWebsolution.de
2006-2024