Sven Rautenberg: Usereingaben bei bestimmten aktionen überprüfen? Passwort, suche

Beitrag lesen

Moin!

Und natürlich noch die Suchfunktion, ich hab mir da was provisorisch aus GET
gebastelt, müssen auch hier die Eingaben gesondert behandelt werden?

Aber auf jeden Fall!

Alles, was im endgültigen SQL-Query dynamisch hineinkommt, muß behandelt werden!

Dummerweise nicht alles gleich.

Das Syntaxhighlighting zeigt im String ja die beiden Variablen schön deutlich an. Und wo Variablen in SQL reinkommen, droht Gefahr.

  
  $sql = "SELECT * from songtexte WHERE $suche_in LIKE '$suche%' ";  

Dummerweise hast du hier nun ausgerechnet zwei Spezialsonderfälle ausgegraben, bei denen dir mysql_real_escape_string() beidesmal nicht exakt helfen kann.

Beginnen wir mit $suche_in. Der Variableninhalt ist eine in der Tabelle existierende Spalte, die durchsucht werden soll.

Den Spaltennamen mit mysql_real_escape_string() zu escapen hilft absolut nicht, weil diese Funktion nur dafür vorgesehen ist, "Daten" innerhalb von einfachen 'Anführungszeichen' zu escapen.

Wenn du die Spaltennamen flexibel haben willst, mußt du anders vorgehen: Ein im Programmcode definiertes Array enthält alle erlaubten, gültigen Spaltennamen, und dein Radiobutton wählt aus diesem Array über den Index nur noch eine der erlaubten Namen aus. Auf diese Weise wird verhindert, dass
a) der Angreifer sich beliebige (auch nichtexistierende) Spaltennamen ausdenken kann (er kann das Formular ja beliebig verändern und dir Blödsinn schicken),
b) der Angreifer bösen SQL-Code in dein Query reinkriegt.

Abgesehen davon wird dein Code dadurch ein Tickchen flexibler, weil die Bezeichner im HTML-Formular nicht mehr mit den Bezeichnern der DB-Spalte übereinstimmen müssen, sondern durch das Array ineinander konvertiert werden.

Das zweite Problem bildet die Variable $suche. Im Prinzip hilft dir mysql_real_escape_string() hier schon, weil es sich, wie auch in allen anderen Anwendungsfällen, um einen String innerhalb von einfachen Anführungszeichen dreht.

Allerdings gibt es hier einen kleinen Unterschied: Du nutzt die Suchfunktion mit LIKE, und das sorgt dafür, dass zwei Zeichen plötzlich Sonderbedeutung erhalten: '%' und '_'. Diese beiden Zeichen sind normal nichts ungewöhnliches und werden daher auch nicht escaped. Müssen sie auch nicht. Aber was ist, wenn der Benutzer in der Datenbank einen Begriff sucht, der ein Prozentzeichen oder einen Unterstrich enthält - aber damit nicht das LIKE-Platzhalterzeichen gemeint ist, sondern ein real in der Datenbank gespeichertes Prozent oder Unterstrich?

Du mußt dich an dieser Stelle also entscheiden, was du willst (Suchen sind hinsichtlich der "korrekten Suchergebnisse" ja durchaus Auslegungssache): Gibt der Benutzer einen String ein, der exakt so gefunden werden soll, oder soll die Nutzung von Datenbank-Wildcardzeichen für die Suche erlaubt sein? Und wäre es in so einem Fall nicht schlauer, wenn man die typischeren Zeichen wie "*" dafür einsetzen würde?

Das Escaping für Wildcardzeichen in MySQL ist jedenfalls relativ simpel: Backslashes sind der Standard, man kann aber im Prinzip jedes beliebige Zeichen verwenden, wenn man es im Query angibt.

Allerdings ist die Backslashverdopplung zu beachten, denn bereits im String enthaltene Backslashes müssen natürlich nochmal escaped werden, damit sie als tatsächliches Zeichen "durchkommen", und nicht zwischendurch als Escape-Zeichen eliminiert werden. Das gilt auch für die durch mysql_real_escape_string() eingeführten Backslashes.

Siehe auch http://dev.mysql.com/doc/refman/5.0/en/string-comparison-functions.html#operator_like.

- Sven Rautenberg

--
"Love your nation - respect the others."