СИЭУиП • ОП.08 Основы проектирования баз данных Теоретический конспект

Теоретический конспект: Безопасность аутентификации в реляционных базах данных

Фундаментальные основы криптографической верификации паролей, пошаговые алгоритмические блок-схемы входа, механизмы защиты от Brute-force атак, ведение журнала событий безопасности Security Audit Log и ролевая авторизация.

1. Архитектурные основы аутентификации в клиент-серверных СУБД

В современных информационных системах форма входа (Login Form) является интерфейсным шлюзом к корпоративной базе данных. Безопасность всей системы опирается на строгое разделение двух понятий:

Фундаментальное правило безопасного хранения: Пароли пользователей никогда не хранятся в открытом виде (Plaintext) и никогда не шифруются обратимыми алгоритмами. Они защищаются с помощью односторонних криптографических хэш-функций с индивидуальной криптографической солью.

Математика соленого хэширования

Хэш-функция $H(m)$ преобразует строку произвольной длины $m$ в строку фиксированной длины (например, SHA-256 дает 256 бит = 64 hex-символа), обладая свойствами необратимости и устойчивости к коллизиям.

Если два пользователя выберут одинаковый пароль P@ssw0rd123, их чистые хэши будут совпадать. Это позволяет злоумышленнику использовать предрассчитанные «радужные таблицы» (Rainbow Tables) для мгновенного взлома миллионов записей. Для предотвращения этой угрозы используется соль (Salt) — случайная последовательность байт (минимум 16 байт), генерируемая криптографическим генератором случайных чисел (CSPRNG) для каждой учетной записи индивидуально при регистрации или смене пароля:

Password_Hash = SHA256(Raw_Password || Salt)

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

2. Пошаговая алгоритмическая блок-схема процесса аутентификации

Процедура входа пользователя в систему представляет собой строгую последовательность транзакционных проверок:

1
Шаг 1: Прием и санитизация параметров входа

Клиент передает login и password по защищенному каналу (TLS). На стороне сервера выполняется тримминг логина, проверка на пустоту и экранирование в параметризованном запросе к СУБД (защита от SQL-инъекций).

↓
2
Шаг 2: Поиск учетной записи в базе данных

Выполняется параметризованный запрос: SELECT user_id, password_hash, salt, role_id, is_active, failed_attempts, locked_until FROM app_users WHERE login = ?;
Ветвление: Если запись не найдена → фиксируется AUTH_FAILURE в журнале аудита, клиенту возвращается нейтральный ответ «Неверный логин или пароль» (защита от User Enumeration).

↓
3
Шаг 3: Проверка статуса учетной записи и временной блокировки

Проверка активности: если is_active = FALSE → отказ с фиксацией ACCOUNT_DEACTIVATED.
Проверка блокировки: если locked_until IS NOT NULL AND locked_until > CURRENT_TIMESTAMP → вход отклоняется, фиксируется ACCOUNT_LOCKED, пользователю сообщается: «Аккаунт временно заблокирован в связи с превышением числа попыток входа. Попробуйте снова через N минут.»

↓
4
Шаг 4: Вычисление соленого хэша и криптографическое сравнение

Сервер извлекает salt из найденной записи и рассчитывает: computed_hash = SHA256(input_password || salt). Выполняется сравнение computed_hash с эталонным password_hash с использованием константного по времени сравнения (для предотвращения атак по времени — Timing Attacks).

↓
5
Шаг 5: Обработка результатов верификации и фиксация в журнале аудита

Случай А (Хэши не совпали):
1. Инкремент счетчика: failed_attempts = failed_attempts + 1.
2. Проверка порога: если failed_attempts >= 3 → выставляется locked_until = CURRENT_TIMESTAMP + INTERVAL '15 minute', фиксируется событие ACCOUNT_LOCKED.
3. Иначе фиксируется AUTH_FAILURE.
4. Возврат клиенту единой ошибки: «Неверный логин или пароль».

Случай Б (Хэши совпали):
1. Сброс счетчика: failed_attempts = 0, locked_until = NULL.
2. Проверка дополнительных политик: не истек ли password_expiry, не выставлен ли флаг must_change_password.
3. Фиксация события AUTH_SUCCESS в security_audit_log.
4. Генерация защищенного токена сессии, передача роли пользователя в клиентское приложение.

3. Структура таблицы журнала аудита событий безопасности (Security Audit Log)

Журнал безопасности является юридически и технически значимым компонентом системы. Он позволяет расследовать инциденты информационной безопасности и выявлять попытки атак в режиме реального времени.

Имя столбца Тип данных Ограничения Назначение и правила заполнения
log_id BIGSERIAL PRIMARY KEY Уникальный монотонно возрастающий идентификатор события аудита.
event_type VARCHAR(30) NOT NULL Категория события: AUTH_SUCCESS (успешный вход), AUTH_FAILURE (неверный пароль или логин), ACCOUNT_LOCKED (аккаунт заблокирован по лимиту), PASSWORD_EXPIRED (пароль просрочен), LOGOUT (завершение сессии).
user_id INT NULL REFERENCES app_users(user_id) Внешний ключ на пользователя. Заполняется NULL, если вход выполнялся под несуществующим логином.
attempted_login VARCHAR(50) NOT NULL Точное строковое значение логина, введенное в форму (критично для расследования попыток вторжения).
ip_address VARCHAR(45) NOT NULL Сетевой адрес рабочей станции клиента (поддерживает IPv4 и IPv6). Необходим для геоблокировок и анализа ботнетов.
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP Метка времени фиксации события с точностью до миллисекунд по серверному времени UTC.
status VARCHAR(20) NOT NULL Результат операции: SUCCESS, FAILED, BLOCKED, RESTRICTED.
details TEXT NULL Диагностический комментарий (например: «Invalid password hash; attempt 2 of 3», «Locked for 15 minutes», «Session initiated»).
Антипаттерн безопасности: Никогда не записывайте в столбец details или в журнал сырой введенный пароль пользователя! Это распространенная уязвимость, превращающая журнал безопасности в источник компрометации паролей.

4. Защита от атак полного перебора (Brute-force Protection)

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

Двухуровневая модель защиты

  1. Счетчик неудачных попыток (failed_attempts): каждый неверный ввод пароля увеличивает значение поля на 1. При достижении критического порога (обычно 3 или 5) аккаунт блокируется.
  2. Временная блокировка (locked_until): запись времени, до наступления которого любые попытки входа блокируются СУБД без проверки пароля. Рекомендуемый интервал блокировки: от 15 минут до 1 часа. По истечении этого времени блокировка снимается автоматически без участия администратора (locked_until <= CURRENT_TIMESTAMP).
-- Проверка статуса блокировки в SQL
IF v_locked_until IS NOT NULL AND v_locked_until > CURRENT_TIMESTAMP THEN
    -- Аккаунт еще заблокирован
    INSERT INTO security_audit_log (event_type, attempted_login, ip_address, status, details)
    VALUES ('ACCOUNT_LOCKED', p_login, p_ip, 'BLOCKED', 'Попытка входа в заблокированный аккаунт');
    RETURN 'ACCOUNT_TEMPORARILY_LOCKED';
END IF;

5. Динамическая настройка элементов экранного интерфейса (RBAC в UI)

После прохождения аутентификации сервер возвращает клиентскому приложению токен сессии и роль пользователя. Интерфейс динамически перестраивается:

6. Вопросы для самопроверки студентов

  1. В чем заключается принципиальное отличие понятий «аутентификация» и «авторизация»?
  2. Почему для защиты паролей нельзя использовать обратимое шифрование с секретным ключом (например, AES-256)?
  3. С какой целью к паролю перед хэшированием добавляется индивидуальная криптографическая соль (salt)?
  4. Опишите алгоритмический шаг, предотвращающий атаку перечисления учетных записей (User Enumeration).
  5. Какую роль играют атрибуты failed_attempts и locked_until в схеме базы данных?
  6. Почему сброс счетчика неудачных попыток в 0 должен осуществляться строго после успешного совпадения хэшей?
  7. Какие обязательные поля должен содержать журнал аудита событий безопасности и почему в него запрещено записывать введенный пароль?
  8. Каким образом ролевая модель (RBAC) влияет на динамическое поведение экранной формы после входа?