От автора: если у вас применяется ввод данных пользователем через веб-страницу с последующей их вставкой в базу данных SQL, существует вероятность, что у вас могут возникнуть проблемы с безопасностью. Связано это с таким явлением, как SQL инъекция. В этой главе мы рассмотрим, как решить данную проблему, и защитить ваши скрипты и инструкции SQL в скриптах на стороне сервера, например, PERL Script.
Инъекция обычно осуществляется, когда вы запрашиваете у пользователя определенные данные, например имя, а вместо этого он вводит инструкцию SQL, которая несанкционированно выполняется в базе данных. Предоставленные пользователем данные всегда должны обрабатываться в базе данных только после их валидации; как правило, она выполняется путем сопоставления с шаблонами.
В приведенном ниже примере для name могут использовать только буквенно-цифровые символы плюс подчеркивание и оно может иметь в длину от 8 до 20 символов (при необходимости вы можете изменить эти правила).
1 2 3 4 5 6 |
if (preg_match("/^\w{8,20}$/", $_GET['username'], $matches)) { $result = mysql_query("SELECT * FROM CUSTOMERS WHERE name = $matches[0]"); } else { echo "user name not accepted"; } |
Давайте рассмотрим следующий пример:
1 2 3 |
// supposed input $name = "Qadir'; DELETE FROM CUSTOMERS;"; mysql_query("SELECT * FROM CUSTOMSRS WHERE name='{$name}'"); |
Предполагается, что вызов функции должен получить запись из таблицы CUSTOMERS, где столбец name соответствует имени, указанному пользователем. Обычно $name содержит только буквенно-цифровые символы и, возможно, пробелы. Но здесь к $name добавляется совершенно новый запрос, который при выполнении вызывает катастрофические последствия; DELETE-запрос удаляет все записи из таблицы CUSTOMERS.
К счастью, если вы используете MySQL, функция mysql_query() не допускает стекирование запросов или выполнение нескольких SQL-запросов в одном вызове функции. Если вы попытаетесь выполнить стек запросов, вызов завершится ошибкой.
Тем не менее, другие расширения базы данных PHP, такие как SQLite и PostgreSQL, принимают стекированые запросы, выполняя все запросы в одной строке, что приводит к серьезным проблемам с безопасностью.
Предотвращение SQL-инъекций
Вы можете контролировать ввод символов escape с помощью скриптовых языков, таких как PERL и PHP. Расширение MySQL для PHP предоставляет функцию mysql_real_escape_string(), которая предотвращает ввод символов, имеющих в MySQL особое значение.
1 2 3 4 5 |
if (get_magic_quotes_gpc()) { $name = stripslashes($name); } $name = mysql_real_escape_string($name); mysql_query("SELECT * FROM CUSTOMERS WHERE name='{$name}'"); |
Проблемы связанные с LIKE
Чтобы не допускать проблем, связанных с LIKE, пользовательский механизм экранирования должен преобразовывать символы «%» и «_» в их буквальные соответствия. Для этого используется функция addcslashes(), которая позволяет указать диапазон символов для экранирования.
1 2 3 4 |
$sub = addcslashes(mysql_real_escape_string("%str"), "%_"); // $sub == \%str\_ mysql_query("SELECT * FROM messages WHERE subject LIKE '{$sub}%'"); |
Источник: //www.tutorialspoint.com/
Редакция: Команда webformyself.
Комментарии (1)