Защитить от внедрения 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;
            }
        }
    }
    ?>

6 ответов

Решение

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

На указанной странице PHP приведен пример внедрения SQL в форму входа в систему.

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

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

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

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

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

mysql_real_escape_string($inputToClean);

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

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

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

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

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

Скорее, чем addslashes ты должен использовать mysql_real_escape_string,

Другие вопросы по тегам