Код-ревью Middle Аутентификация и сессии обновлено
Ревью: вход и сброс пароля на Node.js
Вопрос
Найдите проблемы аутентификации в коде.
app.post('/login', async (req, res) => {
const user = await db.users.findOne({ email: req.body.email });
if (!user) return res.status(404).json({ error: 'Пользователь не найден' });
if (user.password !== md5(req.body.password)) return res.status(401).json({ error: 'Неверный пароль' });
req.session.userId = user.id;
res.json({ ok: true });
});
app.post('/forgot', async (req, res) => {
const token = Math.random().toString(36).slice(2);
await db.resets.insert({ email: req.body.email, token });
await mail(req.body.email, `https://${req.headers.host}/reset?token=${token}`);
res.json({ ok: true });
});
Коротко
Почти все классические ошибки входа в 14 строках. Исправления: одинаковый ответ, медленный хеш, перевыпуск сессии, лимиты, криптографический токен с хешем, сроком и одноразовостью, базовый URL из конфигурации.
Что должен найти ревьюер
- Безопасностьстрока 3Разные ответы и коды для «нет пользователя» и «неверный пароль»: перечисление аккаунтов.
- Безопасностьстрока 4MD5 без соли для паролей: перебирается мгновенно. Нужен Argon2id или bcrypt. Сравнение через
!==тоже не за постоянное время. - Безопасностьстрока 5Идентификатор сессии не перевыпускается при входе (
req.session.regenerate): фиксация сессии. - Безопасностьстрока 1Нет ограничения попыток входа: перебор и credential stuffing.
- Безопасностьстрока 10
Math.randomне криптографический генератор: токен сброса предсказуем. Нуженcrypto.randomBytes(32). - Безопасностьстрока 11Токен хранится в открытом виде и без срока жизни и признака использования.
- Безопасностьстрока 12Ссылка строится из заголовка Host: отравление ссылки сброса.
Разбор
Почти все классические ошибки входа в 14 строках. Исправления: одинаковый ответ, медленный хеш, перевыпуск сессии, лимиты, криптографический токен с хешем, сроком и одноразовостью, базовый URL из конфигурации.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.