Действительно ли этот запрос безопасен от внедрения SQL?

Сценарий находится в PHP и как DB, я использую MySQL. Вот сам сценарий.

$unsafe_variable = $_GET["user-input"];
$sql=sprintf("INSERT INTO table (column) VALUES('%s')",$unsafe_variable);
mysql_query($sql);

Некоторые люди говорят это, если пользователь присваивается ;DROP TABLE blah; представьте в виде строки к переменному $unsafe_variable, он удаляет таблицу.

Но я попробовал этот пример,

http://localhost/test.php?user-input=DROP%20TABLE%20my_table 

Но это не удалило таблицу, но вместо этого вставило новую строку (;DROP TABLE blah;) в таблице.

Кто-либо мог объяснить меня, как возможно напасть на этот сценарий внедрениями SQL?

10
задан Sam 18 August 2014 в 08:56
поделиться

8 ответов

Эта конкретная инъекция не будет работать, поскольку функция PHP mysql_query разрешает только один запрос на вызов. Однако следующее может работать, если столбец имеет первичный или уникальный ключ:

$unsafe_variable = "admin') ON DUPLICATE KEY UPDATE password=MD5(CONCAT('knownsalt', 'newpassword'))#";

Лучше использовать длинную функцию mysql_real_escape_string :

$sql=sprintf("INSERT INTO table (column) VALUES(%s)",
             mysql_real_escape_string($unsafe_variable));
mysql_query($sql);
13
ответ дан 3 December 2019 в 16:29
поделиться

Я думаю, что вам нужно попробовать пример http: //localhost/test.php? User-input = ' ; DROP% 20TABLE% 20my_table '

the '); закрывает значения (сегмент '% s , а затем выдает новую команду, drop table ...

0
ответ дан 3 December 2019 в 16:29
поделиться

ЕДИНСТВЕННЫЙ способ работы с опасными переменными - это параметры привязки.

Пожалуйста, прочитайте эту страницу о том, как предотвратить SQL-инъекции с bobby-tables.com.

2
ответ дан 3 December 2019 в 16:29
поделиться
mysql_real_escape_string($unsafe_variable)
1
ответ дан 3 December 2019 в 16:29
поделиться

Хотя mysql_query позволяет выполнить только один запрос, в целом этот запрос небезопасен. Пример опасного ввода, который может использовать ваш запрос:

'); DROP TABLE my_table; --

'); в начале закроет ваш запрос и вставит пустое значение, но позволит выполнить дополнительные запросы после INSERT. Затем, после удаления таблицы, -- в конце пометит все последующее (т.е. остальную часть вашего запроса) как комментарий.

Для безопасной подготовки ввода для использования в запросе используйте mysql_real_escape_string.

3
ответ дан 3 December 2019 в 16:29
поделиться

Некоторые люди говорят, что если пользователь присваивает строку ;DROP TABLE blah; переменной $unsafe_variable, то она удаляет таблицу.

Разумеется, это не так - но если вы не понимаете, почему, то не сможете определить, безопасен ли ваш код. Вы собираетесь опубликовать здесь каждую строку, чтобы проверить, безопасна ли она?

Не вдаваясь в долгие объяснения того, что делает приведенный выше код и как его скомпрометировать (SQL injection уже очень хорошо документирован в других местах - попробуйте для начала погуглить), вы ВСЕГДА должны убедиться, что любые данные, покидающие ваш PHP-код, имеют правильное представление для того места, куда они направляются.

Для базы данных MySQL это означает либо:

1) использовать вывод mysql_real_escape_string (и убедиться, что вы передаете правильный дескриптор ресурса)

либо

2) использовать привязку параметров.

Правильное обсуждение атак с внедрением кода может легко заполнить несколько сотен страниц - немного многовато для ответа в S.O. запросе.

C.

1
ответ дан 3 December 2019 в 16:29
поделиться

mysql_query () не позволяет выполнять несколько запросов в одной функции. Таким образом, вы не можете ВСТАВИТЬ, а затем УДАЛИТЬ таблицу. Но не стоит полагаться на это как на «безопасность». Вместо этого используйте параметризованные запросы. Ознакомьтесь с библиотекой PHP PDO .

Однако они могли изменить что угодно еще, например, ВЫБРАТЬ поле пароля из другой таблицы в качестве подзапроса для помещения в эту таблицу, чтобы они могли просматривать хэш.

4
ответ дан 3 December 2019 в 16:29
поделиться

Нет, sprintf не избегает использования содержимого:

$unsafe_variable = mysql_real_escape_string($_GET["user-input"]);
$sql=sprintf("INSERT INTO table (column) VALUES('%s')",$unsafe_variable);
mysql_query($sql);
1
ответ дан 3 December 2019 в 16:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: