Я разрабатываю свою собственную фреймворк PHP. Кажется, что все статьи безопасности, которые я прочитал, используют совершенно разные методы аутентификации пользователей, чем я, поэтому я мог бы использовать некоторую помощь в поиске дыр в безопасности.
Некоторая информация, которая может быть полезна до начала. Я использую mod_rewrite для моего MVC-url. Пароли зашифрованы с солью 24 символов, уникальной для каждого пользователя. mysql_real_escape_string и/или переменная typecasting во всем, что происходит, и htmlspecialchars на все, что выходит.
Пошаговый процесс:
Верх каждой страницы:
session_start();
session_regenerate_id();
Если пользователь регистрируется в форме входа в систему, сгенерируйте новый случайный токен, чтобы ввести строку пользователя MySQL. Хэш генерируется на основе пользовательской соли (с момента ее первой регистрации) и нового токена. Храните хэш и имя пользователя открытого текста в переменных сеанса и дублируйте файлы cookie, если отмечен флажок "Запомнить меня".
На каждой странице проверьте наличие файлов cookie. Если файлы cookie установлены, скопируйте их значения в переменные сеанса. Затем сравните $_SESSION ['name'] и $_SESSION ['hash'] с базой данных MySQL. Уничтожьте все файлы cookie и переменные сеанса, если они не совпадают, чтобы они снова вошли в систему.
Если логин действителен, некоторые данные пользователя из базы данных MySQL хранятся в массиве для легкого доступа. До сих пор я предполагал, что этот массив чист, поэтому, ограничивая доступ пользователей, я ссылаюсь на user.rank и отказываюсь от доступа, если он ниже того, что требуется для этой страницы.
Я попытался протестировать все распространенные атаки, такие как XSS и CSRF, но, возможно, я просто недостаточно хорош для взлома моего собственного сайта! Моя система кажется слишком простой, чтобы она была на самом деле безопасной (код безопасности составляет всего 100 строк). Что мне не хватает?
Изменить: для вызова функций с контроллера все, что использует ничего, кроме запросов SELECT, потребует данных $_POST для подтверждения удаления, например, в дополнение к требованиям к рангу пользователя.
Я также потратил много времени на поиск уязвимостей с помощью строки mysql_real_escape, но я не нашел информации, которая является актуальной (все прошло от нескольких лет назад, по крайней мере, и, по-видимому, было исправлено). Все, что я знаю, это то, что проблема связана с кодировкой. Если эта проблема все еще существует сегодня, как ее избежать?
Функция шифрования, которую я заимствовал где-то и изменил:
public function encrypt($str, $salt = NULL) {
if ($salt == NULL) $salt = substr(md5(uniqid(rand(), true)), 0, 24);
else $salt = substr($salt, 0, 24);
return $salt.sha1($salt.$str);
}