Клиентский интерфейс находится под полным контролем пользователя. Любая валидация в браузере или приложении может быть обойдена отправкой прямого HTTP/TCP запроса.
База данных выступает финальным барьером и контрольным центром безопасности:
Вопрос: «Кто вы?»
Процесс установления и проверки подлинности субъекта на основе предъявленных учетных данных (логин + пароль, биометрия, ключ ЭЦП).
POST /api/auth/login [login, password]
Вопрос: «Что вам разрешено делать?»
Проверка прав аутентифицированного субъекта на выполнение конкретных операций (чтение, модификация, удаление, просмотр логов).
RBAC: Role 'Storekeeper' → Allow Goods_Write
Никогда не храните пароли открытым текстом или в обратимом шифровании!
Одинаковые пароли дают одинаковые хэши: SHA256("123456") = e10adc3949...
Злоумышленники используют Rainbow Tables (радужные таблицы) для мгновенного обратного поиска паролей миллионов пользователей.
Индивидуальная случайная строка (16+ байт), генерируемая CSPRNG для каждого пользователя при регистрации:
hash = SHA256(password || salt)
Даже с одинаковым паролем хэши в базе гарантированно уникальны. Радужные таблицы полностью бессильны!
| Атрибут | Тип данных | Назначение в механизме защиты |
|---|---|---|
login |
VARCHAR(50) UNIQUE | Идентификатор учетной записи (уникальный индекс для быстрого точечного поиска). |
password_hash |
CHAR(64) | SHA-256 хэш строки (password || salt) в шестнадцатеричном виде. |
salt |
CHAR(32) | Индивидуальная соль пользователя (16 байт шестнадцатеричной строки). |
is_active |
BOOLEAN | Флаг активности аккаунта (деактивация при увольнении или компрометации). |
failed_attempts |
INT DEFAULT 0 | Счетчик неудачных попыток ввода пароля подряд. |
locked_until |
TIMESTAMP NULL | Временная метка окончания блокировки учетной записи. |
SELECT * FROM app_users WHERE login = ?;AUTH_FAILURE в логе, отдаем клиенту «Неверный логин или пароль» (предотвращение перечисления учетных записей — User Enumeration).locked_until > CURRENT_TIMESTAMP → вход невозможен, статус ACCOUNT_LOCKED, сообщаем пользователю время ожидания.is_active = FALSE → статус ACCOUNT_DEACTIVATED, отказ в авторизации.-- Серверный псевдокод
v_calc_hash := SHA256(input_password || user_record.salt);
IF v_calc_hash = user_record.password_hash THEN
-- ПАРОЛЬ ВЕРЕН!
-- Сбрасываем счетчик и снимаем блокировку:
UPDATE app_users SET failed_attempts = 0, locked_until = NULL WHERE user_id = ...;
-- Записываем успешный вход в аудит:
INSERT INTO security_audit_log (event_type, user_id, status) VALUES ('AUTH_SUCCESS', ..., 'SUCCESS');
ELSE
-- ПАРОЛЬ НЕВЕРЕН! Инкрементируем счетчик неудач...
END IF;
При неверном пароле:
failed_attempts := failed_attempts + 1;
IF failed_attempts >= 3 THEN
locked_until := NOW() + INTERVAL '15 minute';
event := 'ACCOUNT_LOCKED';
ELSE
event := 'AUTH_FAILURE';
END IF;
ACCOUNT_LOCKED немедленно сигнализирует SOC о попытке атаки.Каждое событие аутентификации подлежит обязательной фиксации в неизменяемом логе:
CREATE TABLE security_audit_log (
log_id BIGSERIAL PRIMARY KEY,
event_type VARCHAR(30) NOT NULL, -- AUTH_SUCCESS, AUTH_FAILURE, ACCOUNT_LOCKED
user_id INT NULL REFERENCES app_users(user_id),
attempted_login VARCHAR(50) NOT NULL, -- Введенный логин
ip_address VARCHAR(45) NOT NULL, -- IPv4 / IPv6 рабочей станции
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
status VARCHAR(20) NOT NULL, -- SUCCESS, FAILED, BLOCKED
details TEXT NULL -- Диагностический комментарий
);
Внимание: Запись сырых паролей в журнал аудита категорически запрещена!
| Timestamp | Event Type | Login | IP Address | Status | Аналитический вывод |
|---|---|---|---|---|---|
| 10:41:02 | AUTH_FAILURE | admin | 192.168.1.105 | FAILED | Первая ошибка ввода пароля |
| 10:41:08 | AUTH_FAILURE | admin | 192.168.1.105 | FAILED | Вторая ошибка (интервал 6 сек) |
| 10:41:14 | ACCOUNT_LOCKED | admin | 192.168.1.105 | BLOCKED | Превышен лимит (3 ошибки) → блокировка на 15 мин |
| 10:41:20 | AUTH_FAILURE | admin | 192.168.1.105 | BLOCKED | Попытка подбора во время активного тайм-аута отклонена |
Проверка учетных данных кладовщика, блокировка аккаунта на 15 минут при 3 неверных вводах, запись в Security_Log.
Аудит доступа врачей к персональным данным пациентов, фиксация IP рабочей станции и времени, проверка is_active = FALSE.
Валидация оператора, проверка срока годности пароля (password_expiry), требование смены при первом входе.
Ролевая фильтрация интерфейса: перенаправление студента в ЛК, администратора — в панель управления, аудит сессий.
failed_attempts перед вводом пароля уничтожает всю защиту.security_audit_log.zanyatie.html.Robert'); DROP TABLE Students; --. Когда школа вставила имя ученика через конкатенацию SQL-строки, база данных стерла всех студентов года. Занятие 26 учит будущих разработчиков: использование параметризованных запросов, строгая верификация паролей и ведение журнала безопасности исключают взлом и потерю критических данных!