Сценарий находится на PHP, а в качестве DB я использую MySQL. Вот сценарий.
$unsafe_variable = $_GET["user-input"]; $sql=sprintf("INSERT INTO table (column) VALUES('%s')",$unsafe_variable); mysql_query($sql);
Некоторые люди говорят, что если пользователь назначает ;DROP TABLE blah;
string к переменной $ unsafe_variable удаляет таблицу.
Но я попробовал этот пример,
http://localhost/test.php?user-input=DROP%20TABLE%20my_table
Но он не удалял таблицу, а вместо этого вставил новую таблицу (;DROP TABLE blah;)
в таблицу.
Может ли кто-нибудь объяснить мне, как можно атаковать этот скрипт с помощью SQL-инъекций?
Эта конкретная инъекция не будет работать, поскольку функция mysql_query
PHP mysql_query
только один запрос на вызов. Однако, если column
имеет первичный или уникальный ключ, может работать следующее:
$unsafe_variable = "admin') ON DUPLICATE KEY UPDATE password=MD5(CONCAT('knownsalt', 'newpassword'))#";
Лучше использовать функцию long- mysql_real_escape_string
:
$sql=sprintf("INSERT INTO table (column) VALUES(%s)", mysql_real_escape_string($unsafe_variable)); mysql_query($sql);
mysql_query()
не позволяет выполнять несколько запросов в одной функции. Таким образом, вы не можете ВСТАВИТЬ, а затем ПОСМОТРЕТЬ таблицу. Но вы не должны полагаться на это как на «безопасность». Вместо этого используйте параметризованные запросы. Проверьте библиотеку PDO PHP.
Тем не менее, они могут изменить что угодно, например, SELECTing поле пароля из другой таблицы в качестве подзапроса для размещения в этой таблице, чтобы они могли просматривать хэш.
В то время как mysql_query
позволяет только один запрос выполнить, в общем случае этот запрос небезопасен. Пример опасного ввода, который будет использовать ваш запрос:
'); DROP TABLE my_table; --
');
в начале закроет ваш запрос и введет пустое значение, но позволит выполнить дополнительные запросы после INSERT. Затем после удаления таблицы, в конце будет отмечаться все остальное, следующее (т. Е. Остальная часть вашего запроса) в виде комментария.
Чтобы безопасно подготовить ввод для использования в запросе, используйте mysql_real_escape_string
.