Безопасны ли подготовленные PHP MySQLi запросы со связанными параметрами? - PullRequest
5 голосов
/ 13 октября 2009

Исторически я всегда использовал

mysql_real_escape_string()

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

Теперь, когда я полностью перешел на MySQLi и использую подготовленные запросы со связанными параметрами, эффективно ли я исключил возможность атак SQL-инъекцией?

Правильно ли я сказал, что мне больше не нужно

mysql_real_escape_string()?

Это мое понимание и основа моего проекта: http://sourceforge.net/projects/mysqldoneright/files/Base/MysqlDoneRight-0.23.tar.gz/download

Это не то, что я хочу ошибиться, так как теперь, когда я выпустил это, это может повлиять и на других.

Все введенные пользователем данные теперь будут заканчиваться на bind_parms.
Запросы, представленные на этапе подготовки, являются статическими.

Ответы [ 3 ]

13 голосов
/ 13 октября 2009

Да. Использование подготовленного запроса позволит избежать параметров.

6 голосов
/ 13 октября 2009

Это не так просто. Вы можете использовать связанные параметры вместо интерполяции прикладных переменных в выражения SQL вместо только буквальных значений :

$sql = "SELECT * FROM MyTable WHERE id = ".$_GET["id"]; // not safe

$sql = "SELECT * FROM MyTable WHERE id = ?"; // safe

Но что, если вам нужно сделать часть запроса динамической помимо литерального значения?

$sql = "SELECT * FROM MyTable ORDER BY ".$_GET["sortcolumn"]; // not safe

$sql = "SELECT * FROM MyTable ORDER BY ?"; // doesn't work!

Параметр всегда будет интерпретироваться как значение, а не идентификатор столбца. Вы можете выполнить запрос с ORDER BY 'score', который отличается от ORDER BY score, и использование параметра будет интерпретироваться как первый - постоянная строка 'score', а не значение в столбце с именем score.

Так что во многих случаях приходится использовать динамический SQL и интерполировать переменные приложения в запросе, чтобы получить желаемые результаты. В этих случаях параметры запроса не могут вам помочь. Вы все еще должны быть бдительными и защищаться от ошибок, чтобы предотвратить ошибки SQL-инъекций.

Никакая платформа или библиотека доступа к данным не может сделать эту работу за вас. Вы всегда можете создать строку запроса SQL, которая содержит недостаток внедрения SQL, и вы делаете это до того, как библиотека доступа к данным увидит запрос SQL. Так как же узнать, что является преднамеренным и в чем недостаток?

Вот методы для достижения безопасных запросов SQL:

  • Фильтр ввода. Трассировка любых переменных данных, которые вставляются в ваши SQL-запросы. Используйте входные данные filters для удаления недопустимых символов. Например, если вы ожидаете целое число, убедитесь, что ввод ограничен целым числом.

  • Выход Escape. Выходом в этом контексте может быть запрос SQL, который вы отправляете на сервер базы данных. Вы знаете, что можете использовать параметры SQL-запроса для значений, но как насчет имени столбца? Вам нужна функция экранирования / цитирования для идентификаторов, так же, как старый mysql_real_escape_string() для строковых значений.

  • Обзоры кода. Попросите кого-нибудь стать второй парой глаз и просмотреть ваш код SQL, чтобы помочь вам определить места, где вы не воспользовались двумя вышеупомянутыми методами.

1 голос
/ 13 октября 2009

Когда вы связываете параметры с подготовленным оператором, он автоматически экранирует данные, поэтому вам не следует экранировать его до того, как вы его отправите. Двойной побег обычно плохая вещь. По крайней мере, это приводит к ужасным результатам с дополнительными экранированными символами позже.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...