2017-07-20 5 views
4

warum istMysql, wo oder WHERE begann mit integer seltsamen Ergebnissen

$query = "SELECT * FROM `users` WHERE `id` = '$search' OR `email` = '$search' LIMIT 1"; 

`id` = UNSIGNED INTEGER(10), `email` = VARCHAR(255) 

, warum die Abfrage so sonderbare Ergebnisse, ich glaube, das Bild selbst erklärt, aber ich brauche etwas Wort zu, so ist es hier, wenn Benutzersuche [email protected] oder irgendetwas anderes ist nicht vorhanden, keine Ergebnisse, aber wenn die Zeichenfolge mit der Nummer beginnt und den PRIMARY KEY durchsucht, wird die Zeichenfolge in Ganzzahl umgewandelt, wenn ich [email protected] suche, die ID 2 return, jede gute Erklärung und warum ist das passiert?

enter image description here

enter image description here

enter image description here

+2

** WARNUNG **: Dies hat einige schwerwiegende [SQL injection Bugs] (http://bobby-tables.com/), weil '$ _GET' Daten innerhalb der Abfrage verwendet wird. Wann immer möglich, verwenden Sie ** vorbereitete Aussagen **. Diese sind ziemlich einfach in [mysqli'] (http://php.net/manual/en/mysqli.quickstart.prepared-statements.php) und [PDO] (http://php.net/manual/ en/pdo.prepared-statements.php) wo alle vom Benutzer angegebenen Daten mit einem '?' oder ': name'-Indikator angegeben werden, der später mit' bind_param' oder 'execute' gefüllt wird, je nachdem, welchen du verwendest. ** NIEMALS ** $ _POST', '$ _GET' oder irgendwelche Benutzerdaten direkt in Ihre Anfrage einfügen. – tadman

+1

Im mit PDO, und lassen Sie Benutzer nur Ergebnisse suchen, nie in diesem Fall einfügen, aber nur ich versuche, den Fall zu erklären, so schreibe ich – user259752

+0

Es lenkt von dem, was Sie tun. Wenn möglich, lassen Sie die Platzhalter unverändert. Gute Nachrichten sind, dass diese Passwörter richtig gehashed sind, also haben Sie diesen Teil gesperrt. – tadman

Antwort

4

Das heißt, weil die Typen MySql wandelt automatisch immer dann, wenn ein Bediener mit Operanden von verschiedenen Typen verwendet wird (unter der Annahme, dass Ihre id eine ganze Zahl Spalte).

Siehe the official documentation:

Wenn ein Operator mit Operanden verschiedenen Typen verwendet wird, tritt Typumwandlung auf die Operanden kompatibel zu machen. Einige Konvertierungen finden implizit statt. Zum Beispiel konvertiert MySQL Zahlen automatisch nach Bedarf in Zeichenfolgen und umgekehrt.

und das folgende Beispiel (aus der Dokumentation kopiert):

mysql> SELECT 1 > '6x'; 
     -> 0 
mysql> SELECT 7 > '6x'; 
     -> 1 
mysql> SELECT 0 > 'x6'; 
     -> 0 
mysql> SELECT 0 = 'x6'; 
     -> 1 

Leider scheint es keine Konfiguration, um dieses Verhalten zu verhindern (für SELECT Aussagen zumindest). Was funktionieren könnte eine explizite Umwandlung auf id Säule:

mysql> SELECT CAST(6 AS CHAR) = '6x'; 
     -> 0 
mysql> SELECT CAST(6 AS CHAR) = 6; 
     -> 1 

Aber das scheint immer noch seltsam, da sie einen String-Vergleich für eine Integer-Spalte erzwingt. Der bessere Ansatz wäre wahrscheinlich, solche Fälle in Ihrem PHP-Code zu behandeln (wie in den Kommentaren hervorgehoben).

+0

eine Idee, wie man das verhindert? Sagen mysql nicht die Variable vielleicht erraten? – user259752

+0

Sie könnten versuchen, eine explizite 'CAST' zu machen, damit MySQL dies nicht implizit für Sie vornimmt ... – War10ck

+0

Oder auf der PHP-Seite, konvertieren Sie es, bevor Sie es an MySQL übergeben:' is_int ($ search)? $ suche: 0' (vorausgesetzt, 0 ist nie eine gültige ID) –