Sicherheit von PDO bzgl. SQL-Injection

trench140

Mitglied
Mahlzeit,

habe mich ein wenig zum Thema "PDO" eingelesen und bin auf die Empfehlung gestßen, ab PHP 5.1 selbiges für MySQL-Abfragen zu verwenden.

Ok, super, habe ich erstmal nichts gegen. Nur verstehe ich nicht ganz, warum es so super sicher sein soll.

Nehmen wir z.B. mal den folgenden Code, den ich gebastelt habe:

PHP:
$dbc = new PDO("mysql:host=localhost;dbname=test;","root","");

if(isset($_POST['submit']))
{
	$search = $_POST['search'];
	
	$sql_search = str_replace('*','%',$search);
	
	$sql = "SELECT id,name FROM users WHERE name LIKE :search";
	
	$stmt = $dbc->prepare($sql);
	$stmt->bindParam(':search',$sql_search);
	$stmt->execute();
	
	$rows = $stmt->fetchAll();
        var_dump($rows);
}

Drumherum ist noch nen bisserl Code für Smarty, aber ich denke, dieser und das verwendete Template sind hier unwichtig.

Das Ganze stellt eine simple Suche nach. Ich gebe in ein INPUT-Feld einen zu suchenden String ein, wobei ich "*" als Wildcard nehmen wollte, die dann von PHP durch die MySQL-Wildcards "%" ersetzt werden. Die Idee war einfach, dass ich vermutete, dass bei der Benutzung von PDO solche Zeichen automatisch rausgeschmissen werden.

Problem:
Wenn ich z.B. nach "Wi*" suche, werden mir alle User ausgegeben, deren Nick mit "Wi" beginnt. So sollte es sein.
ABER:
Wenn ich nach "Wi%" suche, kriege ich das gleiche Ergebnis, was aber unerwünscht ist, ich will ja gerade NICHT, dass mir jemand irgendeinen MySQL-Syntax o.ä. unterjubelt.

Also stellt sich mir nun die Frage, warum ist PDO sicherer, als wenn ich mir das Ganze manuell schreibe und "von Hand" unerwüschte Zeichen rausnehme? Oder ist es das gerade nicht, und ich muss das immer noch von Hand machen? Wo liegen denn dann die Vorteile?
Welche Checks sollte ich noch auf $_POST und/oder $_GET laufen lassen, bevor ich die Werte endgültig verwende?

Mich verwirrt einfach, dass dieses "%" ohne jegliche Probleme durchkommt, obwohl die Art und Weise, wie ich die Abfrage (samt prepare und bind) aufgebaut habe z.B. bei Wikipedia als sicher bezeichnet wird (siehe http://de.wikipedia.org/wiki/SQL_Injection#PHP).
 
Problem:
Wenn ich z.B. nach "Wi*" suche, werden mir alle User ausgegeben, deren Nick mit "Wi" beginnt. So sollte es sein.
ABER:
Wenn ich nach "Wi%" suche, kriege ich das gleiche Ergebnis, was aber unerwünscht ist, ich will ja gerade NICHT, dass mir jemand irgendeinen MySQL-Syntax o.ä. unterjubelt.

Natürlich kannst du die Sicherheitsfeatures bei PDO locker umgehen! Einfach mal das Tutorial auf php.net durchlesen, oder andere. Was du machst ist halt error by design:
Die machst eine Suche mit LIKE, und wunderst dich, warum ein % dann entsprechend ausgewertet wird Versteh ich nicht!

ich glaube, du verstehst nicht, was eine SQL Injection ist!

In deinem Fall musst du das Sonderzeichen % gesondert maskieren (ich denke \% reicht, ohne es ausprobiert zu haben!).

Das Problem liegt also in der Natur deiner Abfrage, nicht an PDO!
 
Hi,

darum gings mir ja genau. Was ich bisher gelesen habe lässt PDO aussehen wie die eierlegende Wollmilchsau.
Wenn dem aber eben nicht so ist (was hiermit ja dann bestätigt ist), dann ist mir auch vollkommen klar, dass ich alle Eingaben, die ich kriege, trotzdem maskieren muss.

Ich habe mich nicht gewundert, DASS das % ausgewertet wurde, sondern WARUM, weil ich eben davon ausgegangen bin, dass PDO genau sowas verhindert, indem es selbstständig beim binden der Parameter "gefährliche" Zeichen und Parameter maskiert.
 
Auch wenn es dich schockiert, aber das % gilt bei SQL Injections *NICHT* als "gefährliches" Zeichen!! Gefährliche Zeichen sind Slashes, Hochkommata etc!
Genau deswegen hat dein Problem nichts mit SQL Injections und dem Schutz davor zu tun!!
*Würde* PDO es maskieren, könntest du doch garkein % mehr nutzen, denn ob du es "hart" reinschreibst, oder über eine Variable ist PHP und PDO in dem Moment total egal!!

Thats the difference :)
 
Zurück