Каждый разработчик когда-то писал свою первую форму регистрации. Email, пароль, кнопка «Зарегистрироваться». Казалось бы — что тут может пойти не так?
Спойлер: всё.
Форма регистрации — это не «простая задачка для джуна». Это минное поле, на котором даже сеньоры подрываются с завидной регулярностью. Давай разберём классические ошибки, которые превращают твой код из «рабочего» в «добро пожаловать, хакеры».

1. Пароль хранится в открытом виде
❌ Так делают новички
Сохраняют пароль как обычную строку прямо в базу данных.
INSERT INTO users (email, password)
VALUES ('user@mail.ru', '12345qwerty');Если ты хоть раз писал что-то подобное — поздравляю, ты только что подарил всю базу пользователей любому, кто получит к ней доступ. Админу, стажёру, случайному SQL-дампу на рабочем столе.
✅ Как надо
Хэшировать пароль. Не MD5 (это уже мем), не SHA-256 без соли. Используй bcrypt, argon2 или scrypt.
const bcrypt = require('bcrypt');
const hash = await bcrypt.hash(password, 12); // 12 раундов — нормПравило: если ты можешь прочитать пароль пользователя — ты уже облажался.
2. Нет валидации на сервере
<input type="email" required minlength="6" />«У меня же required стоит, что ещё нужно?»
Нужно понимание, что required в HTML — это просьба, а не закон. Открываем DevTools, убираем атрибут, отправляем пустую строку. Или вообще шлём запрос через curl:
curl -X POST https://yoursite.com/api/register \
-d '{"email": "не-email-вообще", "password": ""}'✅ Как надо
Дублировать ВСЮ валидацию на сервере. Клиентская — для удобства. Серверная — для безопасности.
// Сервер (Express)if (!email || !validator.isEmail(email)) {
return res.status(400).json({ error: 'Невалидный email' });
}
if (!password || password.length < 8) {
return res.status(400).json({ error: 'Пароль слишком короткий' });
}3. SQL-инъекция прямо в форме
Классика, которая живёт и здравствует в 2025 году:
❌ Конкатенация строк в запросе
const query = `INSERT INTO users (email, password)
VALUES ('${email}', '${hashedPassword}')`;Пользователь вводит в поле email:
'; DROP TABLE users; --И привет, таблицы больше нет. Это буквально мем Bobby Tables из xkcd, но люди продолжают так писать.
✅ Параметризованные запросы. Всегда.
await db.query(
'INSERT INTO users (email, password) VALUES ($1, $2)',
[email, hashedPassword]
);Или используй ORM — Prisma, Sequelize, TypeORM — они делают это за тебя.
4. Форма подсказывает, есть ли email в базе
❌ User Enumeration
{ "error": "Пользователь с email ivan@mail.ru уже зарегистрирован" }Теперь злоумышленник может перебирать email-адреса и собрать базу твоих пользователей. Это называется user enumeration, и это реальная уязвимость.
✅ Одинаковый ответ в любом случае
{ "message": "Если указанный email свободен, мы отправим письмо для подтверждения" }Да, это чуть менее удобно для пользователя. Но гораздо безопаснее.
5. Нет rate limiting — привет, брутфорс
Твоя форма принимает 10 000 запросов в секунду? Отлично, бот уже регистрирует аккаунты пачками или перебирает пароли.
✅ Ограничивай количество запросов
const rateLimit = require('express-rate-limit');
const registerLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 минутmax: 5, // максимум 5 попытокmessage: 'Слишком много попыток. Попробуйте позже.'
});
app.post('/api/register', registerLimiter, registerHandler);Добавь CAPTCHA для подозрительных случаев. Да, пользователи её ненавидят. Знаешь, что они ненавидят ещё больше? Когда их аккаунт взламывают.
6. Нет HTTPS
Если форма регистрации работает по HTTP, то пароль летит по сети в открытом виде. Любой в той же Wi-Fi сети (привет, кофейня) может его перехватить.
💡 Факт
В 2025 году отсутствие HTTPS — это даже не ошибка, это заявление: «мне всё равно на моих пользователей».
7. Пароль «123456» проходит валидацию
Ты проверяешь длину пароля. Уже хорошо. Но если password123 и qwerty проходят — ты не помогаешь пользователю, ты помогаешь хакеру.
Что стоит добавить:
Минимальная длина 8+ символов (а лучше 10+)
Проверка по списку утёкших паролей (библиотека
zxcvbnотлично справляется)НЕ требовать обязательно спецсимволы — это приводит к
P@ssw0rd!, что не безопаснее, но бесит пользователей
🚀 Хочешь писать безопасный код? Начни с фундамента
Все эти ошибки — следствие одного: разработчик не до конца понимает, как работает то, что он пишет. Знаешь синтаксис, но не понимаешь, что происходит «под капотом».
В приложении Кодик ты изучаешь программирование через реальные задачи: не просто читаешь теорию, а пишешь код и сразу видишь результат. Идеально и для новичков, и для тех, кто хочет закрепить знания на практике.
А в нашем телеграм-канале (2000+ разработчиков) регулярно выходят разборы ошибок, полезные посты и лайфхаки. Отличный способ повторять программирование прямо в телефоне — между задачами или за кофе.
Форма регистрации — это точка входа в твоё приложение.
Если она дырявая — дырявое всё остальное.
Пиши безопасный код. Или хотя бы начни с bcrypt. 🙃
