Я разрабатываю веб-сайт, и я пытаюсь обеспечить соединение.
Я использовал функцию 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
.