... 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.

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;
}