Защита от SQL-инъекций

Я разрабатываю веб-сайт, и я пытаюсь обеспечить соединение.

Я использовал функцию addslashes в $login чтобы остановить SQL-инъекцию, но некоторые друзья сказали мне, что недостаточно защиты. Однако они не показали мне, как использовать эту уязвимость.

Как я могу / нарушить этот код? Как я могу его защитить?

 <?php if ( isset($_POST) && (!empty($_POST['login'])) && (!empty($_POST['password'])) ) { extract($_POST); $sql = "SELECT pseudo, sex, city, pwd FROM auth WHERE pseudo = '".addslashes($login)."'"; $req = mysql_query($sql) or die('Erreur SQL'); if (mysql_num_rows($req) > 0) { $data = mysql_fetch_assoc($req); if ($password == $data['pwd']) { $loginOK = true; } } } ?> 

Вы должны использовать mysql_real_escape_string для экранирования входных параметров строки в запросе. Используйте литье типа для дезинфекции числовых параметров и белого списка для дезинфекции идентификаторов.

На ссылочной странице PHP приведен пример ввода sql в форме входа.

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

Вы храните свои пароли в открытом виде! Это серьезная проблема безопасности, если я когда-либо видел ее. Что делать с этим: по крайней мере, используйте (для каждого пользователя) соленый хеш пароля, как здесь, например, здесь .

Использование:

 mysql_real_escape_string($inputToClean); 

Есть еще одна зияющая дыра в безопасности – extract . Это может спасти вас от ввода нескольких символов, но для открытия слишком много отверстий, поскольку оно перезапишет любые глобальные переменные.

Что произойдет, если я опубликую это?

 $_POST { 'login' => 'Admin', 'loginOK' => 1 } 

Угадайте, что, $ loginOK теперь == 1, и я войду в систему как Admin.

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

Помимо использования addslashes() , это некоторые случайные проблемы, обнаруженные в этом коде:

  • isset($_POST) всегда TRUE , если вы не запустили его из командной строки. Вероятно, вы можете удалить его.
  • empty() очень сложно. Например, если $password = '0' то empty($password) является TRUE .
  • Вы можете сделать это: if( isset($_POST['login']) && $_POST['login']!='' ){}
  • extract($_POST) – огромная уязвимость: каждый может устанавливать переменные в свой код извне.
  • $password == $data['pwd'] предполагает, что вы сохраняете пароли открытого текста в своей базе данных. Это ужасная практика. Google для «соленого пароля».
  • Вы также можете использовать $loginOK = $password == $data['pwd']; , Вы понимаете, почему? 😉

Вместо addslashes вы должны использовать mysql_real_escape_string .