SQL-инъекция, даже если переменная экранирована - PullRequest
0 голосов
/ 01 октября 2011

SQL-инъекция будет работать только тогда, когда мой запрос будет выглядеть следующим образом:

SELECT * FROM login WHERE id = $my_id_va;

Предположим, что мой запрос

SELECT * FROM login WHERE id = $my_id_va ORDER BY id DESC

Чем я получу следующую ошибку

# 1064 - у вас ошибка в синтаксисе SQL;проверьте руководство, соответствующее вашей версии сервера MySQL, чтобы найти правильный синтаксис для использования рядом с 'order by id desc' в строке 1

Итак, 1 or 1=1; SHOW TABLES не будет работать, верно?

Мой сайт был взломан подряд много раз.

Я хочу один быстрый ответ: Когда мой запрос похож на следующий, какие способы или типы запросов они могут использовать для взлома моего сайта?

SELECT * FROM login WHERE id = $my_id_va ORDER BY id DESC

Как выполнить show table в следующем запросе

SELECT * FROM login WHERE id = $my_id_va ORDER BY id DESC

Я также использую функцию escape для обработки значений строки запроса, например mysql_real_escape_string($my_id_va).Да, очевидно, это для одного связанного взлома, но не уверен.

Добавлен еще

SELECT EventActuallyCharged, EventDate FROM tblevent WHERE EventDate between '2011-07-21 or 1=1; SHOW TABLES --' and '2011-07-31' ORDER BY EventDate DESC

, но таблица показа не работает

Ответы [ 5 ]

2 голосов
/ 01 октября 2011

Int cast

Если id - это число, вы также можете ввести свою переменную. Целые числа безопасны в использовании:

$x = (int)$yourInputVar;
$s = "select * from Table where id = $x";

mysql_real_escape_string

Если вы хотите передать строку, вы можете и должны использовать mysql_real_escape_string, но эта функция экранирует только те символы, которые находятся внутри строки. Вам все еще нужно будет добавлять кавычки вокруг строки, поэтому:

 $x = mysql_real_escape_string('hello');
 $s = "select * from Table where id = $x";

.. приведет к запросу: select * from Table where id = hello. Это явно неверный запрос, так как привет должен быть в кавычках.

Измените запрос на:

 $x = mysql_real_escape_string('hello');
 $s = "select * from Table where id = '$x'";

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

Параметры

Другое решение - использовать параметризованные запросы. Это можно сделать с помощью MySQLi или PDO. Преимущество состоит в том, что вы указываете своей базе данных только то, где переменная должна быть вставлена, и база данных позаботится о экранировании самостоятельно.

Это также может повысить производительность, поскольку эти запросы могут кэшироваться без их параметров, что позволяет более эффективно использовать кэш запросов. Это на самом деле пока не работает в текущих версиях MySQL.

2 голосов
/ 01 октября 2011

Если вы используете PHP5, используйте параметризованный запрос, используйте PDO.

1 голос
/ 01 октября 2011

1. Первый запрос каким-то образом защищен

$sql = sprintf('SELECT * FROM login WHERE id = %d ORDER BY id DESC', mysql_real_escape_string($my_id_va));

2. Второй запрос каким-то образом защищен

$sql = sprintf("SELECT EventActuallyCharged, EventDate FROM tblevent WHERE EventDate BETWEEN '%s' AND '%s' ORDER BY EventDate DESC", 
             mysql_real_escape_string($start_date),
             mysql_real_escape_string($end_date));

Прочитайте документы о sprintf, если вы этого не понимаете.

Однако, как уже говорили другие, было бы очень безопасно, если бы вы использовали параметризованные запросы с таким классом, как PDO или MySQLi .

1 голос
/ 01 октября 2011

Если вы установите $my_id_va в:

1 or 1=1; SHOW TABLES --

-- закомментирует остальную часть команды, фактически завершив ее.

IЯ не уверен, какое влияние mysql_real_escape_string окажет на запрос.То, что вы должны делать, это параметризованные запросы .

1 голос
/ 01 октября 2011

Вы правы, что 1 or 1=1; SHOW TABLES выдаст синтаксическую ошибку, но это сработает:

1 or 1=1 --

- комментирует остальную часть запроса.

В вашем случае это целое число, поэтому вместо mysql_real_escape_string вы можете использовать intval.

...