Сен 26 2008

Ошибки в формах входа — ввод логина и пароля

Раздел: БезопасностьМета @ 21:43

В CakePHP есть собственные компоненты для аутентификации и авторизации, но не многие начинающие программисты ими пользуются, потому что эти компоненты довольно сложные. А формы-то делать надо, иначе как авторизовать пользователя в админку?

Сегодня мне показали еще один пример такой формы. Для простоты объяснения сути заметки, я приведу простой html-код формы:

1
2
3
4
5
<form action="/login" method="POST">
Login name: <input type="text" name="data[Login][username]" size="20" /><br/><br/>
Password: <input type="password" name="data[Login][password]" size="20" /><br/><br/>
<input type="submit" value="Login" />
</form>

Вроде бы здесь все просто и понятно. При отправке формы из нее выдергиваются оба параметра - $this->data['Login']['username'] и $this->data['Login']['password'] и передаются в функцию _try_to_login():

1
2
3
4
5
6
7
8
9
10
11
12
13
function _try_to_login($username, $password)
	{
 
		$hash = md5($password);
		$store = $this->Users->field('password',$username);
 
		if ($hash == $store)
		{
			$_SESSION['admin'] = true;
			$_SESSION['user'] = $username;
		}
 
	}

Что здесь не правильно?

Сразу бросается в глаза использование глобальной переменной $_SESSION — в CakePHP для сохранения переменной в сессию правильнее использовать специальный компонент. Но этот пример тоже работает.

А дальше самое интересное. Обратите внимание, что от пароля берется хеш md5() и сравнивается со значением пароля в базе данных. Это правильно, так безопаснее — не хранить пароль открытым текстом. Но тут никак не проверяется что за данные в $username и $password. И вот в этом главная проблема. SQL-инжекции скорее всего не будет — CakePHP надежно экранирует параметры запроса (надо бы это проверить, кстати). А вот что будет если в этих переменных вовсе и не строковые значения?

Открываем в Опере страничку с формой, выбираем просмотр исходного текста и модифицируем форму вот так:

1
2
3
4
5
<form action="/login" method="POST" name="Login">';
Login name: <input type="text" name="data[Login][username][]" size="20" /><br/><br/>
Password: <input type="password" name="data[Login][password][]" size="20" /><br/><br/>
<input type="submit" value="Login" />
</form>

То есть добавляем к именам параметров квадратные скобки. Это превращает их из строковых переменных в массивы.

При попытке взятия хеша от массива, функция md5() отругивается и возвращает null. При попытке поиска массива в базе данных тоже возвращается null. При сравнении нуля с нулем условие выполняется — и вуаля, пользователь авторизован. Даже без необходимости подбора логина!

Всегда проверяйте типы параметров и их значения.

Теги: , , ,

2 Responses to “Ошибки в формах входа — ввод логина и пароля”

  1. Тамерлан says:

    Убедил! Подписываюсь на ленту! Главное продолжай в том же духе.
    А то остальные проекты про Печеньку умирают как-то быстор :) Удачи.
    Жду новых постов :)

  2. Денис Радченко says:

    А как можно, используя стандартные средства, сделать форму авторизации?

Напиши комментарий!