Почему SELECT ' a ' ='b'=' c ' возвращает 1 в MYSQL?

я делал домашнюю работу для моего класса безопасности с участием SQL-инъекций. Я обнаружил, что могу сделать более короткую SQL-инъекцию, чем типичная ' OR '1'=1 пример. Вместо этого я мог бы сделать '='. Ввод этого в поле пароля типичных полей входа в систему дает SQL-запрос следующим образом:

SELECT * FROM Users WHERE username='user' AND password=''='';

получается, что password=''='' оценивает в 1, позволяя SQL-инъекции работать.

после выполнения еще нескольких тестов я увидел, что если я проверяю, равна ли строка в 0 он возвращает 1:

SELECT 0='a';

так в моем примере password='' возвращает 0 и 0='' в итоге результат 1.

мое тестирование показало мне как это происходит, но я хочу знать почему это происходит (i.e почему 0='a' правда?.

3 ответов


как описано в разделе преобразование типов в оценке выражений, сравнения между строкой и целым числом будут выполняться численно:

  • во всех остальных случаях аргументы сравниваются как числа с плавающей точкой (Real) чисел.

таким образом, операнды преобразуются в числа с плавающей точкой, а затем сравнить.

преобразование строки в float будет учитывать каждый числовой символ (и первый символ периода или возведения в степень) встречается до первого нечислового символа. Поэтому 'hello' или 'a' будет усечено до '' (и, таким образом, приведено к нулю) тогда как '123.45e6foo789' будет обрезать до '123.45e6' (и, таким образом, бросил до 123,450,000).

таким образом, можно видеть, как 0='a' верно: сравнивается как 0=0.

это password=''='' верно (предусмотрено, что password - непустая строка или ненулевое число) происходит потому, что первое сравнение приводит к нулю (false), что заставляет второе сравнение выполняться численно (таким образом, преобразование '' до нуля Для сравнения с нулевым результатом первого сравнения).


Mysql видит сравнение и преобразует строку в целое число,но это приводит к недопустимому целому числу, поэтому он приводит его к 0. 0=0, поэтому его true (1)


для выбора 0= 'a', 0=";

1. type of 0 is int 
2. type of 'a' is char  then CAST( 'a' AS UNSIGNED ) or CAST( '' AS UNSIGNED ) will be 0

преобразовать char в int, то 0=0 оценивается как true в вашем случае 1. В:

select 'A'='a', 0=0, '0'='a',0='a1';

все столбцы будут верны, но:

select 0='1a';

будет false, потому что CAST ('1a' как UNSIGNED ) равно 1.

mysql> SELECT 'asadsadsa' = 'a', 0 = 'az', cast( 'az' AS unsigned ) , 'asadsadsa' = 'a' = 'az', 0 =0;
      +-------------------+----------+--------------------------+--------------------------+------+
      | 'asadsadsa' = 'a' | 0 = 'az' | cast( 'az' AS unsigned ) | 'asadsadsa' = 'a' = 'az' | 0 =0 |
      +-------------------+----------+--------------------------+--------------------------+------+
      |                 0 |        1 |                        0 |                        1 |    1 |
      +-------------------+----------+--------------------------+--------------------------+------+
      1 row in set, 3 warnings (0.00 sec)

      Warning (Code 1292): Truncated incorrect DOUBLE value: 'az'
      Warning (Code 1292): Truncated incorrect INTEGER value: 'az'
      Warning (Code 1292): Truncated incorrect DOUBLE value: 'az'