Moin!
"SELECT * FROM buecher ORDER BY ".$_GET['orby']." ASC";
Was du auf jedenfall tun solltest ist die Endgültige Abfrage immer mit mysql_real_escape durchführen.
Du produzierst hier gerade höheren Unsinn.
Auf der einen Seite forderst du bei einem ziemlich gut durch mysql_real_escape_string() abgesicherten Query noch irgendeine weitergehende Validierung.
Dann aber baust du dem Fragesteller einen Query mit nacktem GET-Parameter zusammen, bei dem man prinzipbedingt keinerlei Escaping einbauen kann, und gehst mit keiner Silbe darauf ein, dass du da gerade das perfekte Einfallstor für SQL-Injection gebaut hast.
Sonst hast du vielleicht irgendwann mal sowas hier ;
"SELECT * FROM buecher WHERE Verlag = 'O'Reilly'"
Dieser Angriff kann nicht stattfinden, da im Query des OP mysql_real_escape_string() für diesen Teil ja verwendet wird.
Die Angabe hinter "ORDER BY" muss allerdings kein Text sein, den man escapen könnte, sondern eine existierende Tabellenspalte. Hier sind also besondere Maßnahmen notwendig, man kann nicht einfach einen beliebig manipulierbaren GET- (oder POST-) Parameter verwenden und direkt in den Query einbauen!
Man muss verhindern, dass irgendetwas anderes als eine der erlaubten, existierenden Spaltennamen in den Query hineinkommt. Das erreicht man am besten dadurch, dass man sich eine Wertetabelle in einem Array ablegt, und als gewünschten Parameter dann nur die jeweiligen Array-Indices verwendet. Das auf- oder absteigende Sortieren könnte man dorthinein ebenso integrieren.
$sortieren = array(1 =>"autor ASC", 2 =>"autor DESC", /*weitere Einträge für andere Spalten*/);
Der Parameter zum Sortieren enthält dann nur eine Zahl, deren Existenz im Array man prüft, und in den Query wandert dann der Inhalt des Arrayfeldes, nicht irgendein vom Benutzer manipulierter String.
Das wäre dann in verständlicher Langform:
if (isset($_GET['order']) && isset($sortieren[$_GET['order']])) {
$sql = "SELECT * FROM tabelle ORDER BY ".$sortieren[$_GET['order']];
}
else
{
$sql = "SELECT * FROM tabelle"; // keine Sortierung - man könnte auch eine Standardsortierung angeben
}
Diese Grundidee ist beliebig ausbaubar. Man kann sich nettere, beschreibendere Indices für das Array ausdenken anstelle der Zahlen, man könnte drüber nachdenken, Spalte und Sortierrichtung getrennt voneinander zu halten, man könnte den Vorgang der Prüfung auf Existenz der gewünschten Spalte auch dynamisch live in der Datenbank erledigen (z.B. mit SELECT * FROM TABELLE LIMIT 1
, und dann die gelieferten Keys von mysql_fetch_assoc() angucken), wenn man eher etwas wie ein Admin-Interface baut.
Um eine höchst sorgfältige Prüfung dessen, was außerhalb der einfachen Anführungszeichen '' in den SQL-Query hineinkommt, kommt man aber nicht herum. Nur Stringdaten sind verhältnismäßig einfach übergebbar, indem man sie einfach nur escaped.
- Sven Rautenberg
"Love your nation - respect the others."