Тема 4. Проектирование структур баз данных — Практическое занятие №9: проект БД и форма входа, этап 2. Интеграция экранной формы входа с реляционной базой данных, криптографическая проверка пароля, механизмы защиты от подбора (Brute-force), журнал аудита безопасности Security Audit Log и ролевая адаптация интерфейса.
Вид занятия: Практическое занятие (лабораторно-практический практикум).
Длительность: 2 академических часа (основной регламент — 80 минут, сокращенный регламент — 60 минут).
Место в учебном плане: Занятие №26 логически развивает этап 1 практического занятия №9 (занятие 25). Если на этапе 1 студенты проектировали графический интерфейс формы входа и таблицы пользователей/ролей, то на этапе 2 осуществляется глубокая серверно-логическая связка клиентской формы с базой данных: обеспечение криптографической устойчивости, отражение атак перебора и разграничение полномочий.
failed_attempts, locked_until); спроектировать структуру таблицы аудита безопасности Security_Audit_Log; настроить ролевое управление элементами экранного интерфейса на клиенте.Методический план предусматривает два регламента проведения с сохранением ключевых дидактических единиц:
| Этап занятия | Основной (80 мин) | Сокращенный (60 мин) | Содержание и акценты деятельности преподавателя |
|---|---|---|---|
| 1. Организационный момент и мотивационный кейс | 5 минут | 3 минуты | Приветствие, фиксация явки. Разбор реального кейса: атака словарем на веб-сервис без rate-limiting (1000 запросов/сек привели к компрометации 15% аккаунтов). Формулировка проблемы: одной визуальной формы недостаточно, защита требует транзакционного протокола СУБД. |
| 2. Актуализация знаний и алгоритмический разбор | 15 минут | 12 минут | Фронтальный опрос: разница между аутентификацией и авторизацией. Разбор 5-шагового алгоритма верификации: 1) Поиск логина; 2) Проверка тайм-аута блокировки; 3) Хэширование введенного пароля с индивидуальной солью; 4) Безопасное сравнение; 5) Запись в журнал аудита. |
| 3. Инструктаж и сквозная демонстрация эталона | 10 минут | 8 минут | Демонстрация работы SQL-процедуры верификации на проекторе. Имитация 3 неверных попыток: демонстрация перехода статуса в блокировку на 15 минут (locked_until = NOW() + INTERVAL '15 minute'). Показ записей в таблице Security_Audit_Log. |
| 4. Самостоятельная практическая работа в zanyatie.html | 40 минут | 30 минут | Индивидуальное выполнение практических протоколов по 4 вариантам (Склад, Медицина, Банк, Образование). Консультирование студентов, контроль корректности SQL-транзакций, предотвращения Race Condition и динамического переключения UI. |
| 5. Экспертный разбор типовых ошибок | 5 минут | 4 минуты | Разбор характерных багов: сброс счетчика ошибок при неверном пароле, отсутствие аудита неудач, отсутствие блокировки по времени. |
| 6. Итог занятия, рефлексия, оценивание и ДЗ | 5 минут | 3 минуты | Демонстрация слайда 15 с веб-комиксом Bobby Tables (xkcd #327). Оценивание по 4-балльной рубрике (.rubrika.md). Пояснение условий сдачи резервного дистанционного ДЗ. |
Для надежного функционирования подсистемы аутентификации таблица пользователей расширяется защитными атрибутами, а все события входа фиксируются в неизменяемом журнале аудита:
-- 1. Таблица учетных записей пользователей
CREATE TABLE app_users (
user_id SERIAL PRIMARY KEY,
login VARCHAR(50) NOT NULL UNIQUE,
password_hash CHAR(64) NOT NULL, -- SHA-256 хэш (hex-строка)
salt CHAR(32) NOT NULL, -- Индивидуальная криптографическая соль (16 байт hex)
role_id INT NOT NULL REFERENCES app_roles(role_id),
is_active BOOLEAN NOT NULL DEFAULT TRUE,
failed_attempts INT NOT NULL DEFAULT 0, -- Счетчик подряд идущих неудачных попыток
locked_until TIMESTAMP NULL, -- Время, до которого вход заблокирован
password_expiry DATE NOT NULL, -- Срок годности пароля
must_change_password BOOLEAN NOT NULL DEFAULT FALSE,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-- 2. Таблица журнала аудита событий безопасности
CREATE TABLE security_audit_log (
log_id BIGSERIAL PRIMARY KEY,
event_type VARCHAR(30) NOT NULL, -- 'AUTH_SUCCESS', 'AUTH_FAILURE', 'ACCOUNT_LOCKED', 'PWD_CHANGE'
user_id INT NULL REFERENCES app_users(user_id) ON DELETE SET NULL,
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 -- Дополнительная диагностическая информация
);
CREATE INDEX idx_security_log_lookup ON security_audit_log (attempted_login, timestamp DESC);
Процедура верификации выполняет следующие обязательные шаги транзакционно:
login = p_login. Если учетная запись не найдена, регистрируется событие AUTH_FAILURE с причиной «Пользователь не найден», при этом на клиенте выдается обобщенное сообщение: «Неверный логин или пароль» (предотвращение атак перечисления учетных записей — User Enumeration).locked_until IS NOT NULL AND locked_until > CURRENT_TIMESTAMP, вход отклоняется с фиксацией ACCOUNT_LOCKED, интерфейс сообщает время окончания блокировки.is_active = FALSE, аккаунт деактивирован администратором — отказ в доступе.v_computed_hash = SHA256(p_password || salt).failed_attempts = failed_attempts + 1.failed_attempts >= 3 (порог системы): устанавливается locked_until = CURRENT_TIMESTAMP + INTERVAL '15 minute', регистрируется событие ACCOUNT_LOCKED.AUTH_FAILURE.failed_attempts = 0, locked_until = NULL.AUTH_SUCCESS в журнале аудита.failed_attempts должен происходить строго после успешной верификации, а не при начале попытки входа!
После возврата сервером успешного ответа и идентификатора роли клиентское приложение настраивает отображение элементов:
security_audit_log.display: none или удалены из DOM).| Типичная ошибка | В чем заключается риск | Педагогический прием устранения |
|---|---|---|
| Хранение паролей в открытом виде | Утечка дампа базы раскрывает пароли всех сотрудников сервиса, нарушает требования регуляторов и ФЗ-152. | Показать на экране утилиту генерации SHA-256; объяснить необходимость соли для предотвращения атак по «радужным таблицам» (Rainbow Tables). |
| Дифференциация сообщений об ошибках («Пользователь не найден» vs «Неверный пароль») | Уязвимость User Enumeration: злоумышленник автоматизированно составляет валидный список существующих сотрудников компании. | Объяснить принцип единого нейтрального ответа в UI: «Неверный логин или пароль», при этом детальную причину фиксировать исключительно в закрытом журнале аудита. |
| Обнуление счетчика неудач на клиенте | Клиентский код в браузере легко модифицируется через DevTools, обнуление счетчика на клиенте делает защиту бесполезной. | Подчеркнуть принцип Zero Trust: состояние счетчика failed_attempts должно храниться и инкрементироваться строго внутри СУБД. |
| Игнорирование записи неудачных попыток в лог | Служба безопасности не видит факта распределенной атаки подбора паролей. | Разобрать пример построения дашборда безопасности: всплеск событий AUTH_FAILURE с одного IP сигнализирует о Brute-force атаке. |
В ходе практического занятия рекомендуется использовать следующие приемы активного обучения:
failed_attempts, блокировка locked_until на 15 мин при 3 ошибках.