Інші відповіді вже охоплюють те, що вам потрібно знати. Але, можливо, це допоможе пояснити ще:
Є ДВА РЕЧІ, які вам потрібно зробити:
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>
дані. Справді, навіть трохи технічний користувач міг додати додаткові опції за допомогою консолі браузера. якщо ви зберігаєте білий список масиву доступних значень і порівнюєте вхідні дані з ним, ви можете пом'якшити це (і потрібно, бо це запобігає небажаним значенням)