Почему 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'