Тема 4. Проектирование структур баз данных — Практическое занятие №9: проект БД и форма входа, этап 1

1. Проблема: цена ошибки при проектировании аутентификации

Статистика инцидентов ИБ

  • 81% взломов корпоративных систем происходят из-за кражи, подбора или утечки учетных данных.
  • Хранение паролей в открытом виде (plaintext) — грубейшее нарушение стандартов безопасности (ГОСТ Р 57580, PCI DSS, GDPR).
  • Утечка дампа базы данных раскрывает учетные записи всех сотрудников компании за доли секунды.

Инженерная цель этапа 1

  • Спроектировать реляционную модель подсистемы безопасности в СУБД.
  • Реализовать одностороннее криптографическое хэширование паролей с солью (SHA-256 + Salt / bcrypt).
  • Разработать эргономичный и защищенный макет диалогового окна формы входа (Login Dialog).
  • Обеспечить фиксацию инцидентов в журнале аудита безопасности.

2. Базовые концепции: Идентификация vs Аутентификация vs Авторизация

1. Идентификация

Вопрос: «Кто ты?»

Субъект сообщает свое уникальное системное имя (логин, email, табельный номер).

SELECT id FROM users WHERE login = :login;

2. Аутентификация

Вопрос: «Докажи это!»

Проверка подлинности через секрет (хэш пароля, криптографическая соль, OTP-код из SMS).

verify_hash(input_pwd, salt, db_hash);

3. Авторизация

Вопрос: «Что тебе можно?»

Проверка прав и ролевых полномочий (RBAC) к модулям, таблицам и операциям базы данных.

IF role = 'Admin' THEN GRANT ACCESS;

3. Архитектура реляционных сущностей безопасности

1. Справочник roles

  • id (PK) — первичный ключ.
  • role_name — уникальное имя роли (NOT NULL, UNIQUE).
  • role_description — текстовое описание полномочий.
  • Принцип наименьших привилегий (Least Privilege).

2. Таблица users

  • id (PK) — суррогатный ключ (BIGINT).
  • login — уникальный логин (UNIQUE).
  • salt — криптографическая соль.
  • password_hash — хэш-образ пароля.
  • role_id (FK) — внешняя ссылка.
  • is_active — флаг мягкой блокировки.

3. Журнал audit_logs

  • id (PK) — ключ события.
  • user_id (FK) — субъект действия.
  • attempted_login — имя попытки.
  • event_type — SUCCESS / FAILURE.
  • ip_address — адрес терминала.
  • event_time — точная метка времени.

4. DDL-проектирование таблиц безопасности в SQL

CREATE TABLE roles (
    id SERIAL PRIMARY KEY,
    role_name VARCHAR(50) NOT NULL UNIQUE,
    role_description VARCHAR(255) NOT NULL,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL
);

CREATE TABLE users (
    id BIGSERIAL PRIMARY KEY,
    login VARCHAR(50) NOT NULL UNIQUE,
    salt VARCHAR(64) NOT NULL,
    password_hash VARCHAR(128) NOT NULL,
    role_id INTEGER NOT NULL,
    is_active BOOLEAN DEFAULT TRUE NOT NULL,
    failed_attempts SMALLINT DEFAULT 0 NOT NULL,
    locked_until TIMESTAMP WITH TIME ZONE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL,
    CONSTRAINT fk_users_roles FOREIGN KEY (role_id) 
        REFERENCES roles(id) ON UPDATE CASCADE ON DELETE RESTRICT
);

5. Почему одного хэширования недостаточно?

Угроза радужных таблиц (Rainbow Tables)

  • Хэш-функции детерминированы: один и тот же пароль всегда порождает одинаковый хэш.
  • SHA256("admin123") = 240be518fabd2724...
  • Злоумышленники заранее сгенерировали терабайты готовых цепочек «пароль → хэш».
  • Взлом дампа базы без соли выполняется мгновенным поиском по индексу!

Решение: криптографическая соль (Salt)

  • Генерация случайной криптостойкой строки (16–32 байта) для каждого пользователя.
  • Формула: Hash(password + salt).
  • Даже при одинаковых паролях «123456» у 100 пользователей получаются 100 совершенно разных хэшей в БД!
  • Стоимость предварительного расчета возрастает до астрономических величин.

6. Сравнение криптографических алгоритмов

SHA-256 + Salt

  • Длина хэша: 256 бит = 64 символа HEX (VARCHAR(64)).
  • Особенность: очень быстрый алгоритм.
  • Риск: на специализированных фермах с GPU возможен перебор миллиардов хэшей в секунду.
  • Назначение: академический стандарт, проверка контрольных сумм и базовое изучение.

bcrypt (Индустриальный стандарт)

  • Длина хэша: 60 символов (VARCHAR(60)).
  • Формат: $2b$[cost]$[salt22][hash31].
  • Особенность: настраиваемый фактор замедления (cost factor). Каждое увеличение на 1 удваивает время расчета.
  • Устойчивость: аппаратно защищен от параллельного взлома на GPU.

7. Проектирование таблицы журнала аудита (Audit Log)

CREATE TABLE audit_logs (
    id BIGSERIAL PRIMARY KEY,
    user_id BIGINT,
    attempted_login VARCHAR(50) NOT NULL,
    event_type VARCHAR(30) NOT NULL, 
    ip_address VARCHAR(45) NOT NULL,
    user_agent VARCHAR(255),
    event_time TIMESTAMP WITH TIME ZONE 
        DEFAULT CURRENT_TIMESTAMP NOT NULL,
    details TEXT,
    CONSTRAINT fk_audit_users 
        FOREIGN KEY (user_id) 
        REFERENCES users(id) 
        ON DELETE SET NULL
);

CREATE INDEX idx_audit_time 
    ON audit_logs(event_time);

Инженерные требования к аудиту

  • Анонимные попытки: user_id может быть NULL, если логин не найден в базе, но attempted_login сохраняется всегда!
  • Фиксация IP: тип VARCHAR(45) гарантирует хранение как IPv4, так и длинных адресов IPv6.
  • Типы событий: LOGIN_SUCCESS, LOGIN_FAILURE, PASSWORD_RESET, LOCKOUT.
  • Индексация: индекс по event_time необходим для оперативного мониторинга инцидентов.

8. Архитектура экранной формы входа (Login Dialog)

Компоненты диалога

  • Поле логина: автофокус при открытии, отключение спеллчекера.
  • Поле пароля: маскирование символов точками, кнопка «показать пароль» (toggle visibility).
  • Кнопка отправки: состояние Loading/Disabled при выполнении сетевого запроса.
  • Контейнер ошибки: вывод подсказок без раскрытия внутренней архитектуры.

Жизненный цикл формы (State Machine)

  1. IDLE — ожидание ввода учетных данных.
  2. CLIENT_VALIDATION — проверка формата логина и непустого пароля.
  3. SUBMITTING — блокировка кнопки, вызов API.
  4. AUTH_ERROR — нейтральная ошибка, сброс пароля.
  5. SUCCESS — переход к рабочему месту роли.

9. Безопасность UX: Защита от перечисления пользователей

Опасный антипаттерн (User Enumeration)

Сообщение 1: «Пользователь с таким логином не существует»

Сообщение 2: «Введен неверный пароль к логину admin»

Уязвимость: Злоумышленник по сообщению понимает, существует ли аккаунт, и собирает базу валидных логинов компании!

Безопасный инженерный стандарт

Единое нейтральное сообщение:

«Неверный логин или пароль»

Злоумышленник не получает информации о наличии пользователя в базе данных.

Дополнительно: задержка ответа одинакова для существующих и несуществующих аккаунтов (защита от Timing-атак).

10. Защита от перебора паролей (Brute-Force & Lockout)

Счетчик неудачных попыток в БД

UPDATE users 
SET failed_attempts = failed_attempts + 1,
    locked_until = CASE 
      WHEN failed_attempts + 1 >= 5 
      THEN NOW() + INTERVAL '15 minutes'
      ELSE NULL 
    END
WHERE login = :login;

Эшелонированные барьеры защиты

  • UI Throttling: задержка кнопки «Войти» на 2–3 секунды после каждого неверного ввода.
  • CAPTCHA: подключение графического теста после 3 неудачных попыток.
  • Account Lockout: временная блокировка аккаунта на 15 минут после 5 ошибок подряд.
  • Сброс счетчика: обнуление failed_attempts = 0 при успешном входе.

11. Отраслевые требования к вариантам практической работы

Вариант 1: Оптовый склад

Роли: Кладовщик, Менеджер, Бухгалтер, Администратор.

Особенность входа: выбор филиала/склада из выпадающего списка при авторизации; изоляция видимости номенклатуры.

Вариант 2: Медицинская поликлиника

Роли: Врач, Регистратор, Главврач.

Особенность входа: вход по табельному номеру врача + второй фактор (2FA / TOTP-код) для доступа к электронным картам.

Вариант 3: Банковский терминал

Роли: Оператор, Кредитный инспектор, Контролер.

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

Вариант 4: Образовательный портал

Роли: Студент, Преподаватель, Куратор, Родитель.

Особенность входа: защищенный сценарий «Забыли пароль» с генерацией одноразовой криптографической ссылки сброса.

12. Пошаговый алгоритм выполнения практического задания

  1. Шаг 1: Открыть интерактивный лист zanyatie.html, ввести свою фамилию и учебную группу.
  2. Шаг 2: Переключиться на назначенный вариант предметной области (Варианты 1–4).
  3. Шаг 3: Спроектировать DDL-спецификацию таблиц users, roles, audit_logs с обязательными полями (salt, password_hash, role_id, is_active).
  4. Шаг 4: Разработать экранный макет диалога Login Dialog с учетом отраслевых требований безопасности.
  5. Шаг 5: Ответить на контрольные вопросы самопроверки и сохранить отчет (кнопка «Сохранить прогресс»).

13. Критерии оценивания работы (0–4 балла)

2 балла

Структура таблиц безопасности

  • Корректные типы первичных и внешних ключей.
  • Наличие полей salt, password_hash, is_active.
  • Спецификация таблицы аудита.

1 балл

Макет формы входа (Login Dialog)

  • Продуманная эргономика UI/UX.
  • Маскирование символов пароля.
  • Отраслевая специфика варианта (филиал, 2FA, экранная клавиатура, сброс).

1 балл

Выводы и самопроверка

  • Обоснование выбора алгоритма хэширования.
  • Аргументация нейтральных сообщений об ошибках.
  • Полнота ответов на контрольные вопросы.

14. Безопасность форм и баз данных: Little Bobby Tables

xkcd 327: Exploits of a Mom
Тематический интернет-мем: «Exploits of a Mom» (культовый веб-комикс про «Little Bobby Tables», xkcd №327).
Автор: Randall Munroe. Первоисточник: xkcd.com/327. Лицензия: Creative Commons Attribution-NonCommercial 2.5 Generic (CC BY-NC 2.5).
Связь с темой занятия: Мама назвала сына Robert'); DROP TABLE Students; --. Когда школа вставила имя ученика в базу через простую конкатенацию строки, база данных стерла всех студентов за учебный год. На этапе проектирования проекта БД и формы входа важно помнить: строгая валидация полей входа, параметризованные запросы и хранение хэшированных паролей с солью исключают подобные катастрофы!
1 / 15