Каковы наилучшие методы предотвращения инъекций sql?

Я провел некоторое исследование и все еще смущен. Это результат моего исследования. Может кто-нибудь прокомментировать и посоветовать, как я могу сделать это лучше, или если есть твердая реализация рок, которую я могу использовать?

Способ 1:

array_map('trim', $_GET); array_map('stripslashes', $_GET); array_map('mysql_real_escape_string', $_GET); 

Способ 2:

 function filter($data) { $data = trim(htmlentities(strip_tags($data))); if (get_magic_quotes_gpc()) $data = stripslashes($data); $data = mysql_real_escape_string($data); return $data; } foreach($_GET as $key => $value) { $data[$key] = filter($value); } 

Оба метода, которые вы показываете, не рекомендуются

Одеяло «дезинфекция» данных является контрпродуктивным, поскольку данные необходимо дезинфицировать по-разному в зависимости от того, как он будет использоваться: использование его в запросе базы данных требует различной санитарии от вывода его в HTML или использования его в качестве параметров в вызове командной строки и т. д. и т. д.

Лучший способ сделать санитарию – это непосредственно перед использованием данных. Таким образом, программисту легко понять, действительно ли все данные дезинфицируются.

Если вы используете семейство функций mysql_* , mysql_real_escape_string() для каждого аргумента, который вы используете в запросе:

 $safe_name = mysql_real_escape_string($_POST["name"]); $safe_address = mysql_real_escape_string($_POST["address"]); $result = mysql_query ("INSERT INTO table VALUES '$safe_name', '$safe_address'"); 

Если вы используете семейства функций PDO или mysqli , вы можете использовать параметризованные запросы, которые устраняют большинство проблем с SQL-инъекциями – во всех повседневных.

Вполне возможно писать безопасные запросы с помощью mysql_* , а также вполне возможно ввести дыру безопасности в PDO-запросе, но если вы начинаете с нуля, сразу же используйте PDO или mysqli.

Используйте strip_tags() только в том случае, если вы планируете выводить введенные пользователем данные в HTML; обратите внимание, что вам необходимо сделать дополнительные htmlspecialchars() чтобы надежно предотвратить атаки XSS.

Единственный способ очистки санитарии, который имеет некоторые достоинства, – это

  if (get_magic_quotes_gpc()) $data = stripslashes($data); 

который отфильтровывает слой экранирования, добавленный устаревшей функцией «магических кавычек» более ранних версий PHP.

Я думаю, что этого достаточно (EDIT: с $ data мы имеем в виду здесь, например, одно текстовое поле из формы, $_POST['example'] т. Д.):

 if (get_magic_quotes_gpc()) $data = stripslashes($data); $data = mysql_real_escape_string($data); 

Обычно я делаю первый, когда получаю данные $ _POST или $ _GET (перед тестированием ввода), а последний – перед или во время составления запроса sql.

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

Вы также можете:

  • Исключить все входные данные пользователя, используемые для БД, используя mysql_real_escape_string (или mysqli_variant)
  • Используйте подготовленные операторы (с mysqli_ или PDO)

Обратите внимание, что вы должны отключить magic_quotes, если это возможно. Если он включен, просто используйте stripslashes (как в вашем примере), поскольку он устарел, и вы не должны полагаться на него.

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

Мне нравится наброски типов всякий раз, когда вы имеете дело с int s; например

 $id=(int)$_GET['id']; if($id<1){//I generally don't pass around 0 or negative numbers //Injection Attempt die('Go Away'); } //Continue with the number I **know** is a number 

Ну, среди ваших кодов функция mysql_real_escape_string () связана с SQL-инъекциями. Однако, совершенно неуместно.
И этого недостаточно.

Фактически, эта функция должна использоваться только с цитированными строками.
И это бесполезно для всего остального. Поэтому в любом другом случае должны быть приняты другие меры предосторожности.

Для полного объяснения см. Мой более ранний ответ: на PHP при отправке строк в базу данных следует позаботиться о недопустимых символах с помощью htmlspecialchars () или использовать регулярное выражение?

Все остальные функции, которые вы используете, вообще не имеют отношения к SQL.
Обратите внимание, что использование strip_tags и htmlentities избыточно. и htmlentities является устаревшим.
Я бы использовал только htmlspecialchars() вместо этих двух, а не перед вставкой в ​​базу данных, но перед отправкой в ​​браузер.