English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
如果您通过网页获取用户输入的数据并将其插入一个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-атак и т.д.
В языках скриптов, таких как 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-запросов, если пользователь вводит значения, содержащие "_" и "%", может возникнуть такая ситуация: пользователь хотел всего лишь запросить "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