Другие ответы уже охватывают то, что вам нужно знать. Но, возможно, это поможет прояснить еще кое-что:
Есть две вещи , которые вы должны сделать:
1. Подтвердите данные формы.
Как ясно показывает ответ Джонатана Хоббса , выбор элемента html для ввода формы не обеспечивает надежной фильтрации.
Проверка обычно выполняется таким образом, чтобы данные не изменялись, но снова отображалась форма с полями, помеченными как «Исправьте это».
Большинство фреймворков и CMS имеют конструкторы форм, которые помогут вам с этой задачей. И не только это, они также помогают против CSRF (или «XSRF»), который является еще одной формой атаки.
2. Очистить / избежать переменных в операторах SQL.
.. или позвольте заранее подготовленным утверждениям сделать работу за вас.
Если вы создаете инструкцию (My) SQL с любыми переменными, предоставленными пользователем или нет, вам нужно экранировать и заключить эти переменные в кавычки.
Как правило, любая такая переменная, которую вы вставляете в инструкцию MySQL, должна быть либо строкой, либо чем-то, что PHP может быть надежно преобразовано в строку, которую MySQL может переварить. Например, числа.
Для строк вам затем нужно выбрать один из нескольких методов для экранирования строки, то есть заменить любые символы, которые будут иметь побочные эффекты в MySQL.
- В старой школе MySQL + PHP mysql_real_escape_string () выполняет эту работу. Проблема в том, что об этом слишком легко забыть, поэтому вы обязательно должны использовать подготовленные операторы или построители запросов.
- В MySQLi вы можете использовать подготовленные операторы.
- Большинство фреймворков и CMS предоставляют построители запросов, которые помогут вам с этой задачей.
Если вы имеете дело с числом, вы можете опустить экранирование и кавычки (вот почему подготовленные операторы позволяют указать тип).
Важно отметить, что вы избегаете переменных для оператора SQL, а НЕ для самой базы данных . В базе данных будет храниться исходная строка, но для оператора требуется экранированная версия.
Что произойдет, если вы пропустите одно из них?
Если вы не используете проверку формы , но дезинфицируете свой ввод SQL, вы можете увидеть все виды плохих вещей, но вы не увидите SQL-инъекцию! (*)
Во-первых, это может привести ваше приложение в состояние, которое вы не планировали. Например, если вы хотите рассчитать средний возраст всех пользователей, но один пользователь указал возраст «aljkdfaqer», ваш расчет не удастся.
Во-вторых, могут быть всевозможные другие виды атак с использованием инъекций, которые вам необходимо учитывать: например, пользовательский ввод может содержать javascript или другой материал.
Все еще могут быть проблемы с базой данных: например, если поле (столбец таблицы базы данных) ограничено 255 символами, а строка длиннее этого. Или, если поле принимает только числа, а вместо этого вы пытаетесь сохранить нечисловую строку. Но это не «инъекция», это просто «сбой приложения».
Но даже если у вас есть свободное текстовое поле, в котором вы разрешаете любой ввод без проверки вообще, вы все равно можете сохранить его в базе данных точно так же, если вы правильно экранируете его, когда он переходит к оператору базы данных. Проблема возникает, когда вы хотите где-то использовать эту строку.
(*) или это было бы что-то действительно экзотическое.
Если вы не экранируете переменные для операторов SQL , но проверили ввод формы, вы все равно можете видеть, что происходит плохое.
Во-первых, вы рискуете, что при сохранении данных в базе данных и их повторной загрузке это уже не будут те же данные, «потерянные при переводе».
Во-вторых, это может привести к неправильным операторам SQL и, таким образом, к сбою вашего приложения. Например, если какая-либо переменная содержит кавычки или двойные кавычки, в зависимости от того, какой тип кавычек вы используете, вы получите недопустимый оператор MySQL.
В-третьих, это все еще может вызывать SQL-инъекцию.
Если ваш пользовательский ввод из форм уже отфильтрован / проверен, намеренная инъекция SQl может стать менее вероятной, ЕСЛИ ваш ввод сведен к жестко запрограммированному списку параметров или если он ограничен числами. Но любой ввод произвольного текста можно использовать для SQL-инъекции, если вы не экранируете переменные в операторах SQL должным образом.
И даже если у вас вообще нет ввода формы, у вас все равно могут быть строки из всех источников: чтение из файловой системы, извлечение из Интернета и т. Д. Никто не может гарантировать, что эти строки безопасны.
<select>
ввести любые значения, которые он пожелает, в ваш ввод. Действительно, даже немного технически подготовленный пользователь может добавить дополнительные параметры с помощью консоли браузера. если вы сохраните белый список доступных значений массива и сравните входные данные с ним, вы можете смягчить это (и вы должны, потому что это предотвращает нежелательные значения)