Выбрать главу

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

При вводе или смене пароля проверяйте его на слабость. Прежде всего недопустим пустой пароль. Помимо традиционного пробивания по словарю я советую самостоятельно дописать специфические проверки под ваше приложение в зависимости от заполняемых пользователем полей при регистрации. Итак, пользователь вводит о себе какую-то информацию. Система не должна позволить ему задать себе пароль, равный логину, имени, фамилии, дате рождения в вариациях формата (то есть если введена дата рождения 05.10.1992, то пароль не должен быть таким: ”05.10.92“, ”05/10/92“, ”05-10-92“, ”051092“, ”1992“ и так далее), номеру телефона или ICQ, городу и тому подобное. Эту информацию часто можно легко найти на других сайтах и форумах в профиле и попробовать в качестве пароля.

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

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

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

Развивая тему алгоритмов проверки пароля на слабость, можно дополнить предыдущий пример функции совсем уж маньячными проверками. Например, так:

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

Подумайте и о возможности перехвата пароля при входе или смене. Раз уж кто-то может слушать трафик пользователя (например, недобросовестный админ прокси, провайдер либо сосед пользователя по сети (если они на хабах, а не на свитчах)), то, ясное дело, применение MD5 и тому подобных алгоритмов избавления от необходимости передавать пароль открытым текстом не имеют смысла (потому что злоумышленник подставит зашифрованный или захеширванный пароль в запрос на вход и, даже не зная пароля, войдет). Остается шифровать само HTTP-соединение, то есть использовать HTTPS.

Никогда не отправляйте пароли методом HTTP/GET. Только POST. Во-первых, они сохраняются в логах Apache, во-вторых, в зависимости от настроек браузера, могут попасть в историю посещения, в логи другого сервера или хуже того – в публичную статистику через Referer.

25.

У сеанса обязательно должен быть (настраиваемый) тайм-аут (максимальная длительность бездействия пользователя). Ваша многогранная защита может сойти на нет, если сам пользователь или обстоятельства подвергнут опасности сеанс.

Представьте себе такие ситуации:

• Пользователь не завершил сеанс и закрыл браузер. После его ухода можно запустить браузер и пройтись по нескольких URL из истории. Нетрудно догадаться, что если системе никто не объяснил, что пользователь с таким IP, с таким User-Agent, с такими Cookie и т.п. сеанс не завершил, то он продолжится как ни в чем не бывало.

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

• Человек торопится уходить, но еще есть время поработать в вашей системе. За пять минут до его ухода происходит авария и электропитания в здании нет. Запасного тоже нет (у машины не было бесперебойника). Человеку некуда деваться (ждать нельзя), он уходит. Через час электропитание восстановлено. Включаем компьютер, запускаем браузер и опять получаем в свое распоряжение тот самый сеанс.

Если ситуация из последнего примера кажется вам чересчур надуманной, смотрите пункт 18 (про маньяков и закон подлости).

Вывод: должен быть тайм-аут. Делается просто. При входе и успешном выполнении любого допустимого действии, которое выполняется авторизованным пользователем, для его логина или id записывается текущее время (то есть время последней активности). А до выполнения такого действия текущее время сравнивается со временем, записанным в вышеописанной таблице для данного пользователя. Если разница превышает тайм-аут, то пользователю работать дальше запрещается, а его сеанс завершается. Здесь же заодно подходящее место для вывода формы входа.

26. Отладка.

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

Рассмотрите варианты, как можно организовать отладочный режим:

• Приложение отлаживается на сервере, недоступном снаружи (самый безопасный вариант).

• Недокументированная настройка – переключение в отладочный режим.

• Доступ к отладочной информации имеют пользователи либо по IP, либо только определённые учетные записи.

Итак, что же я понимаю под отладочной информацией.

• Время выполнения всего скрипта или его части (функции или куска кода).

• Количество SQL-запросов, их текст, время их выполнения.

• Нагрузка на процессор скриптом, базой, расход памяти.

• Сообщения об ошибках и предупреждения интерпретатора в браузер, а не в лог.

• Дампы выполнения вспомогательных команд, вызывавшихся во время исполнения скрипта.

• Трассировка стека.

• Дамп переменных окружения, HTTP-запроса.

• На страницы вместе с информацией из базы выводятся внутренние идентификаторы (например, id пользователей, сессий, новостей, статей, событий, да, в принципе, любые идентификаторы данных, которые порой очень облегчают разбор происходящего без лишних подглядываний в базу).

Пара слов о реализации. Я предпочитаю заводить переменную вроде $DEBUG. В разработке она = 1, иначе это релиз. И теперь можно писать либо так:

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

Либо так:

Например, в отладке в списках можно к тексту элемента дописывать его ID в базе. Или добиться, чтобы в отладке проект не выдавал предупреждений на JavaScript при выходе или удалении информации, так как вам это скоро надоест, а данные тестовые – их не жалко в случае чего (да и бэкапы вы всё равно делаете, не так ли?).

Internal Server Error – знакомо? Пусть в релизе так и остаётся. Так как уж очень интересные вещи порой Perl может поведать взломщику. Максимум, что тут можно сделать, так это назначить в apache

ErrorDocument 500 /500.html

и написать там по-русски об ошибке с учетом того, какое у вас приложение. А технические детали вы в логах почитаете.

Вроде красиво, вроде безопасно… но так неудобно отлаживать – приходится все время читать хвост error_log. Есть способы выводить многие ошибки в браузер. Почему не все? Дело в том, что ошибка может возникнуть ещё до выполнению приведенных ниже трюков, и они просто не успеют отработать.

Итак, направить ошибки в браузер в режиме отладки можно либо по-старому: