Letzte Kommentare

PlayJaps: Ïðèâåò Æäåì íà ñòîïî÷êó :) Êëàññíî! KAPOW…

Klaus: Guten Tag, ich habe Ihre Seite über die Google-Suche gefunden, weil…

Michael: Hallo Josef, Wo du die gezeigte Funktion hinein kopierst ist ziemlich…

Josef: Guten Tag! Ich habe mich mit der PHP-Template-Thematik noch nie beschäftigt.…

L3o: Danke, das rettet mir den Tag, ich schreibe nämlich im Moment gerade selbst…

Zum mitnehmen

Für Programmierer:

Für Anwender:

SQL Injection: Wie verantwortungslos kann man sein?

Tags: php, mysql 1 Kommentar

... und wie Paranoid sollte man sein? Grunsätzlich gilt: Besser zu Paranoid, denn Sicherheitslücken im nachhinein zu finden und auszubessern ist meist sehr mühsam. Und oft ist ein sicheres Script nicht mehr Arbeit als ein unsicheres.

SQL Injection ist ein alt bekanntes Sicherheitsproblem, welches - wie so oft - bei ungefilterten Benutzereingaben liegt. Darum sollten Eingaben vom Client immer überprüft (validiert) werden.

Beispiel

Ein sehr arges Beispiel das ich erst vor kurzem gesehen habe:
http://example.com/seite.php?table=benutzer&field=passfoto&where=kuerzel='AB'

Das ist jetzt kein Scherz. Nicht dass ihr denkt ich erfinde da etwas... muss ich garnicht!
Die GET Parameter werden so direkt in die SQL Query eingefügt:

SELECT passfoto FROM benutzer WHERE kuerzel='AB'

Jetzt könnte man natürlich die Parameter ändern und eine beliebige Query ausführen und somit an Passwörter oder andere Daten kommen.

Sichere Queries

Das open source CMS Drupal hat da eine einfache aber sehr schöne Lösung eingebaut. Die Query wird dabei mit sprintf formatiert, wobei z.B. %d für Zahlen stehen und NUR Zahlen in diesem Argument erlaubt sind. Also ist weiteres validieren unnötig. Ich habe diese Funktion abgeändert und vereinfacht, sodass diese mit jedem Script verwendet werden kann:

<?php
function db_query($query) {
    
$args func_get_args();
    if(
count($args) > 1) {
        unset(
$args[0]); // Query should not be escaped.
        
$args array_map('mysql_real_escape_string'$args);
        
array_unshift($args$query); // Add query again for sprintf.
        
$query call_user_func_array('sprintf'$args);
    }
    
$result mysql_query($query);
    return 
$result;
}
// Example
db_query('SELECT * FROM table WHERE typ=%d AND name="%s"'$_GET['typ'], $_GET['name']);
?>

Magic Quotes abschalten

Diese sehr umstrittene PHP Einstellung stellt (wenn sie aktiviert ist) allen Metazeichen (vorallem einfache Anführungszeichen) von der Clientseite (POST, GET, Cookie,...) automatisch einen Backslash bevor. Dadurch kann kein oder nur erschwert Code in Queries gebracht werden.

Diese Einstellung muss also deaktiviert werden, wenn man Benutzereingaben selber überprüft (also auch bei Verwendung der db_query funktion). Am besten in der php.ini "magic_quotes_runtime" auf 0 setzen, oder per Script deaktivieren falls man keinen Zugang zur php.ini hat:

<?php
ini_set
('magic_quotes_runtime'0); // Try to turn magic_quotes off
// Stripslashes in deep if needed.
if(get_magic_quotes_gpc()) {
    
$_GET stripslashes_r($_GET);
    
$_POST stripslashes_r($_POST);
    
$_COOKIE stripslashes_r($_COOKIE);
}
function 
stripslashes_r($value) {
    if(
is_array($value)) {
        
$value array_map('stripslashes_r'$value);
    }
    else {
        
$value stripslashes($value);
    }
   return 
$value;
}
?>

Wer diese Funktionen benutzt ist auf der sicheren Seite und viel mehr Arbeit ist es garnicht, da diese Code Teile in jedem Script gleich verwendet werden können.

Kommentare

Klaus am 26. November 2011, 21:44 Uhr

Guten Tag,

ich habe Ihre Seite über die Google-Suche gefunden, weil in Verbindung mit der Funktion mysql-real-escape-string seit einem Monat ein Fehler auf einer der Seiten auftritt.

Nach einem auszufüllenden Kontaktformar und nach dem absenden wird im Browser folgende Fehlermeldung angezeigt:

Warning: mysql_real_escape_string() [function.mysql-real-escape-string]: Access denied for user 'student'@'localhost' (using password: NO) in /usr/www/users/student/class/Db.inc on line 50

Warning: mysql_real_escape_string() [function.mysql-real-escape-string]: A link to the server could not be established in /usr/www/users/student/class/Db.inc on line 50

Diese Meldungen erscheinen mehrfach im Browserfenster.
Der ehemalige Programmierer ist nicht mehr tätig, ein neuer noch nicht in Sichweite, sodass ich momentam ziemlich hilflos vor diesem Problem stehe.

Hier der entsprechende Code in der Datei 'DB-inc':

function executeQuery( $queryString ) {
if( get_magic_quotes_gpc() ) {
$queryString = stripslashes($queryString);
}
$args = func_get_args();
if( count($args) > 1 ) {
$queryString = array_shift($args);
$queryString = str_replace( '?', '%s', $queryString );
if (phpversion() >= '4.3.0') {
$args = array_map( 'mysql_real_escape_string', $args );
}
else {
$args = array_map( 'mysql_escape_string', $args );
}
array_unshift( $args, $queryString );
$queryString = call_user_func_array('sprintf',$args);
}

// $this->logMessage( $queryString, 0 );

$result = @mysql_query( $queryString );
if( mysql_errno() ) {
$this->logMessage(mysql_errno().': '.mysql_error(), 2);
return;
}
return $result;
}

Kommentar schreiben

  • Erlaubte HTML Tags: <a> <code> <em> <strong> <small> <ul> <ol> <li> <blockquote>
  • Zeilen und Absätze werden automatisch formatiert.
  • Web und E-Mail Adressen werden automatisch umgewandelt.