English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

SQL-инъекции и MySQL

如果您通过网页获取用户输入的数据并将其插入一个MySQL数据库,那么就有可能发生SQL注入安全的问题。

本章节将为大家介绍如何防止SQL注入,并通过脚本来过滤SQL中注入的字符。

所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。

我们永远不要信任用户的输入,我们必须认定用户输入的数据都是不安全的,我们都需要对用户输入的数据进行过滤处理。

以下示例中,输入的用户名必须为字母、数字及下划线的组合,且用户名长度为 8 到 20 个字符之间:

if (preg_match("/^\w{8,20}$/", $_GET['username'], $matches))
{
   $result = mysqli_query($conn, "SELECT * FROM users 
                          WHERE username=$matches[0]");
}
 else 
{
   echo "username 输入异常";
}

让我们看下在没有过滤特殊字符时,出现的SQL情况:

// 设定$name 中插入了我们不需要的SQL语句
$name = "Qadir'; DELETE FROM users;";
 mysqli_query($conn, "SELECT * FROM users WHERE name='{$name}'");

В приведенных выше инъекционных предложениях мы не фильтруем переменную $name, в $name внедрены SQL-запросы, которые мы не хотим, что приведет к удалению всех данных из таблицы users.

В PHP mysqli_query() не позволяет выполнять несколько SQL-запросов, но в SQLite и PostgreSQL можно выполнять несколько SQL-запросов одновременно, поэтому нам нужно строго проверять данные пользователей.

Для предотвращения инъекции SQL, мы должны учитывать несколько ключевых моментов:

  • 17. Никогда не доверяйте вводу пользователя. Проверяйте ввод пользователя, можно использовать регулярные выражения или ограничивать длину; проверяйте одиночные кавычки и т.д. Преобразование с помощью двойных "-" и т.д.

  • 16. Никогда не используйте динамически скомпилированные SQL, используйте параметризованные SQL или хранимые процедуры для выполнения запросов и операций с данными.

  • 15. Никогда не используйте базы данных с правами администратора, для каждого приложения используйте отдельное соединение с базой данных с ограниченными правами.

  • 14. Не храните конфиденциальную информацию напрямую, шифруйте или hash-ите пароли и другие чувствительные данные.

  • 13. Приложение должно предоставлять как можно меньше информации об исключениях,最好是 использовать пользовательские сообщения об ошибках для упаковки исходных сообщений об ошибках

  • 12. Обычные методы обнаружения инъекции SQL обычно включают использование вспомогательного программного обеспечения или платформы веб-сайта, такие как инструмент для обнаружения инъекции SQL jsky, инструмент безопасности платформы Yisi и т.д. MDCSOFT SCAN и т.д. Использование MDCSOFT-IPS может эффективно защитить от инъекции SQL, XSS-атак и т.д.

Предотвращение инъекции SQL

В языках скриптов, таких как Perl и PHP, вы можете escaping данных пользователя для предотвращения инъекции SQL.

PHP расширение MySQL предоставляет функцию mysqli_real_escape_string() для escaping特殊的ых символов ввода.

if (get_magic_quotes_gpc()) 
{
  $name = stripslashes($name);
}
$name = mysqli_real_escape_string($conn, $name);
 mysqli_query($conn, "SELECT * FROM users WHERE name='{$name}'");

Инъекция в like-выражение

При выполнении like-запросов, если пользователь вводит значения, содержащие "_" и "%", может возникнуть такая ситуация: пользователь хотел всего лишь запросить "abcd_", но результатом было "abcd_", "abcde", "abcdf" и т.д.; при запросе "30%" (Примечание: тридцать процентов) также могут возникнуть проблемы.

В PHP-скрипте мы можем использовать функцию addcslashes() для обработки таких ситуаций, как показано в следующем примере:

$sub = addcslashes(mysqli_real_escape_string($conn, "%something_"), "%_");
// $sub == \%something\_
 mysqli_query($conn, "SELECT * FROM messages WHERE subject LIKE '{$sub}%'");

Функция addcslashes() добавляет обратную косую черту перед указанными символами.

Формат синтаксиса:

addcslashes(string,characters)
ПараметрыОписание
строкаОбязателен. Указать строку, которую нужно проверить.
символыОпционально. Указать символы или диапазон символов, которые должны быть затронуты функцией addcslashes().

Конкретные примеры можно найти здесь:Функция addcslashes() PHP