8.1.7 Безопасные рекомендации по программированию клиентов
Приложения-клиенты, обращающиеся к MySQL, должны следовать приведенным ниже рекомендациям, чтобы избежать неправильной интерпретации внешних данных или раскрытия конфиденциальной информации.
Правильная обработка внешних данных
Приложения, которые обращаются к MySQL, не должны доверять данным, введенным пользователями. Пользователи могут попытаться обмануть ваш код, введя специальные или экранированные последовательности символов в веб-формы, URL-адреса или любые другие используемые вами приложения. Убедитесь, что ваше приложение остается безопасным, если пользователь попытается выполнить SQL-инъекцию, введя что-то вроде ; DROP DATABASE
mysql; в форму. Это крайний пример, но из-за подобных техник, применяемых хакерами, могут произойти серьезные утечки и потери данных, если вы к ним не подготовились.
Распространённая ошибка — защита только строковых значений данных. Не забывайте проверять числовые данные также. Если приложение генерирует запрос, например, SELECT * FROM table WHERE
ID=234, когда пользователь вводит значение 234, пользователь может ввести значение 234 OR 1=1, чтобы заставить приложение сгенерировать запрос SELECT * FROM table WHERE ID=234 OR
1=1. В результате сервер извлекает все строки в таблице. Это приводит к раскрытию всех строк и чрезмерной нагрузке на сервер. Самый простой способ защиты от этого типа атаки — использование одинарных кавычек вокруг числовых констант: SELECT * FROM table WHERE ID='234'. Если пользователь вводит дополнительную информацию, она становится частью строки. В числовом контексте MySQL автоматически преобразует эту строку в число и удаляет все последующие нечисловые символы.
Иногда люди думают, что если база данных содержит только общедоступные данные, то её не нужно защищать. Это неверно. Даже если разрешено отображать любую строку в базе данных, вы всё равно должны защищаться от атак типа отказа в обслуживании (например, тех, которые основаны на технике, описанной в предыдущем абзаце, которая заставляет сервер тратить ресурсы). В противном случае ваш сервер перестанет реагировать на законных пользователей.
Список проверок:
Включите строгий режим SQL, чтобы сообщить серверу о необходимости более строгой проверки принимаемых значений данных. См. Раздел 7.1.11, «Режимы SQL сервера».
Попробуйте ввести одинарные и двойные кавычки (
'и") во все ваши веб-формы. Если вы получите какой-либо вид ошибки MySQL, немедленно разберитесь с проблемой.Попробуйте изменить динамические URL-адреса, добавив
%22("),%23(#) и%27(') к ним.Попробуйте изменить типы данных в динамических URL-адресах с числовых на символьные, используя символы, показанные в предыдущих примерах. Ваше приложение должно быть защищено от этих и аналогичных атак.
Попробуйте ввести символы, пробелы и специальные символы вместо чисел в числовые поля. Ваше приложение должно удалить их перед передачей в MySQL или же сгенерировать ошибку. Передача непроверенных значений в MySQL очень опасно!
Проверьте размер данных перед передачей их в MySQL.
Подключите ваше приложение к базе данных с использованием имени пользователя, отличного от того, которое используется для административных целей. Не предоставляйте вашим приложениям никакие разрешения, которые им не нужны.
Многие интерфейсы программирования приложений предоставляют возможность экранирования специальных символов в значениях данных. При правильном использовании это предотвращает ввод пользователем значений, которые приводят к генерации приложением операторов с другим эффектом, чем вы предполагали:
MySQL SQL операторы: Используйте подготовленные SQL-запросы и принимайте значения данных только с помощью заготовок; см. Раздел 15.5, «Подготовленные операторы».
MySQL C API: Используйте вызов API. В качестве альтернативы, используйте интерфейс подготовленных операторов C API и принимайте значения данных только с помощью заготовок; см. .
MySQL++: Используйте модификаторы
escapeиquoteдля потоков запросов.-
PHP: Используйте либо расширения
mysqliилиpdo_mysql, а не устаревшее расширениеext/mysql. Предпочтительные API поддерживают улучшенный протокол аутентификации MySQL и пароли, а также подготовленные операторы с заготовками. См. также .Если необходимо использовать устаревшее расширение
ext/mysql, то для экранирования используйте функцию а не илиaddslashes(), потому что только чувствительна к кодировке символов; другие функции могут быть “обходными” при использовании (некорректных) многобайтовых кодировок символов. Perl DBI: Используйте заготовки или метод
quote().Java JDBC: Используйте объект
PreparedStatementи заготовки.
Возможно, подобные возможности есть и в других интерфейсах программирования.
Правильная обработка сообщений об ошибках MySQL
Приложение должно перехватывать ошибки, возникающие при выполнении SQL-запросов на сервере MySQL, и обрабатывать их должным образом.
Информация, возвращаемая в сообщении об ошибке MySQL, не лишняя, поскольку она важна для отладки MySQL с помощью приложений. Например, практически невозможно отладить сложный запрос типа соединения 10-way join SELECT без предоставления информации о том, какие базы данных, таблицы и другие объекты связаны с проблемами. Таким образом, сообщения об ошибках MySQL иногда обязательно должны содержать ссылки на имена этих объектов.
Простой, но небезопасный подход приложения при получении такой ошибки от MySQL — перехватить её и отобразить клиенту без изменений. Однако, раскрытие информации об ошибках — это известный тип уязвимости приложения (CWE-209), и разработчик приложения должен убедиться, что в приложении нет этой уязвимости.
Например, приложение, отображающее сообщение, подобное этому, раскрывает клиенту имя базы данных и таблицы, что клиент может попытаться использовать:
ERROR 1146 (42S02): Table 'mydb.mytable' doesn't exist
Вместо этого приложение при получении такой ошибки от MySQL должно записывать соответствующую информацию, включая информацию об ошибке, в безопасное место аудита, доступное только авторизованному персоналу. Приложение может возвращать пользователю что-то более общее, например, “Внутренняя ошибка”.
© 2025 Oracle
Licensed under the GPLv2 License.