Информационная безопасность
Аутентификация и авторизация
Цели урока
- Различать AuthN и AuthZ и знать, какой HTTP-код (401 vs 403) соответствует каждому
- Объяснять, почему bcrypt/Argon2 безопаснее SHA-256 для хранения паролей
- Проектировать RBAC-систему с иерархическим наследованием ролей
- Распознавать сценарии, где RBAC недостаточно и нужен ABAC
Предварительные знания
2012 год. Хакер за несколько часов уничтожил цифровую жизнь журналиста Мэта Хонана - iCloud, Gmail, Twitter, MacBook удалён удалённо. Ни один пароль не взломан. Один звонок в техподдержку Apple, адрес и последние 4 цифры кредитки - и оператор сбросил пароль. Один фактор аутентификации стоит всего. AuthN и AuthZ - не академические концепции, а то, что стоит между данными пользователей и злоумышленником.
- **Каждый веб-проект:** login, регистрация, JWT, роли - AuthN/AuthZ есть везде, от TODO-app до банка
- **Здравоохранение (HIPAA):** врач должен видеть только своих пациентов - ABAC policy, не RBAC роль
- **Финтех:** 3D Secure, биометрия, аппаратные ключи - MFA как стандарт индустрии
Роберт Сэндью и рождение RBAC
В 1992 году исследователи NIST Феррайоло и Кун представили формальную модель RBAC на конференции. До этого системы использовали DAC (Discretionary Access Control) или MAC (Mandatory Access Control) - оба громоздкие в администрировании. RBAC стал стандартом ANSI/INCITS в 2004 году. Сегодня RBAC есть в каждой операционной системе, базе данных и облачной платформе. Просто, масштабируемо, аудитируемо - три качества, которых хватает для большинства задач.
Аутентификация: установление личности
2012 год. Журналист Мэт Хонан теряет всю цифровую жизнь за несколько часов - iCloud, Gmail, Twitter, MacBook удалён удалённо. Ни один пароль не был взломан. Атакующий позвонил в техподдержку Apple, назвал адрес и последние 4 цифры кредитки (оба - публичные данные), и оператор сбросил пароль. Один фактор аутентификации - один фактор провала. Это не история о плохих паролях. Это история о неправильной архитектуре.
**Аутентификация (AuthN)** - процесс подтверждения личности. «Кто это?» Три категории факторов:
**Хранение паролей - НИКОГДА plain text, НИКОГДА MD5/SHA-256!** В 2016 году утекла база LinkedIn с 164 миллионами паролей, хешированных SHA-1 без соли. За 72 часа 90% паролей были расшифрованы. SHA-256 считается быстро - это **плохо** для паролей, потому что атакующий перебирает миллиарды хешей в секунду.
| Алгоритм | Подходит для паролей? | Скорость GPU (хешей/сек) | Вердикт |
|---|---|---|---|
| MD5 | НЕТ | ~60 миллиардов | Сломан, забудьте о нём |
| SHA-256 | НЕТ | ~10 миллиардов | Слишком быстрый для паролей |
| **bcrypt** | ДА | ~10 тысяч | Стандарт, настраиваемая сложность |
| **Argon2** | ДА | ~1 тысяча | Лучший выбор (победитель PHC 2015) |
**Argon2** лучше bcrypt, потому что требует много **памяти** (memory-hard), а не только CPU. GPU хорошо считает хеши, но имеет ограниченную память. Argon2id - рекомендуемый вариант для новых проектов.
Пользователь входит с паролем и SMS-кодом. Затем система запрашивает секретный вопрос (имя питомца). Сколько факторов аутентификации задействовано?
Авторизация: что разрешено?
**Аутентификация** ответила: «Это Алексей». Теперь вопрос: «Что Алексею можно делать?» Может ли он редактировать чужие посты? Видеть зарплаты коллег? Удалять пользователей? Это **авторизация (AuthZ)**. Два разных механизма, два разных middleware, два разных HTTP-кода ошибок.
**Частая путаница:** 401 Unauthorized означает «не аутентифицирован». А 403 Forbidden - «аутентифицирован, но не авторизован». Названия HTTP-кодов исторически неточны. Это ловушка на каждом интервью.
**OAuth 2.0** - стандарт для делегированной авторизации. Когда приложение просит «Войти через Google», оно не получает пароль от Google. Вместо этого Google выдаёт **токен с ограниченными правами** (scope): например, только чтение email и имени. Никакого доступа к почте или документам.
| Механизм | Для чего | Где хранить |
|---|---|---|
| **Session cookie** | Классический веб (server-side state) | httpOnly, secure, SameSite cookie |
| **JWT** | Stateless API, микросервисы | Memory / httpOnly cookie (не localStorage!) |
| **OAuth 2.0** | Делегирование доступа третьим лицам | Access token (короткоживущий) + Refresh token |
| **API Key** | Машинный доступ (CI/CD, интеграции) | Env variables, secret manager |
**НИКОГДА не храните JWT в localStorage!** Любой XSS-скрипт читает localStorage и крадёт токен. Используйте httpOnly cookie - JavaScript не имеет к ним доступа.
Пользователь авторизован с ролью 'editor'. Он пытается удалить аккаунт другого пользователя (DELETE /api/users/123). Сервер возвращает ошибку. Какой HTTP-код корректен?
RBAC: Role-Based Access Control
Как организовать авторизацию для 10 000 пользователей? Назначать каждому индивидуально - кошмар. **RBAC** решает: вместо назначения прав пользователям напрямую, создаются **роли** с наборами **разрешений**, затем роли назначаются пользователям. Kubernetes, AWS IAM, PostgreSQL - все используют RBAC под капотом.
**Principle of Least Privilege:** каждый пользователь должен иметь минимально необходимые права. Новый сотрудник получает роль viewer, а не admin. Это снижает ущерб от компрометации аккаунта - принцип, применяемый везде от Kubernetes ServiceAccount до AWS IAM.
| Роль | posts:read | posts:create | posts:delete | users:manage |
|---|---|---|---|---|
| viewer | да | нет | нет | нет |
| editor | да | да | нет | нет |
| moderator | да | да | да | нет |
| admin | да | да | да | да |
В реальных системах RBAC реализуется через библиотеки: **CASL** (JavaScript), **Casbin** (Go/Node/Python), **Spring Security** (Java). Не пишите свою систему ролей с нуля - это источник ошибок безопасности.
**Role explosion:** если для каждого edge-case создавать новую роль, в системе с 50 ресурсами и 4 действиями может появиться 200+ ролей. Это признак, что RBAC не справляется и нужен ABAC.
В системе есть роли: admin, manager, employee. Manager может всё, что employee, плюс утверждение отпусков. Admin - всё, что manager, плюс управление пользователями. Как лучше реализовать?
ABAC: Attribute-Based Access Control
RBAC отлично работает для статических ролей. Но что если правила зависят от **контекста**? «Врач видит только своих пациентов», «сотрудник редактирует только свои отчёты», «доступ к финансовым данным только из офисной сети в рабочее время». Для таких случаев - **ABAC**. AWS IAM использует именно ABAC: `aws:SourceIp`, `aws:CurrentTime` - это атрибуты контекста.
**ABAC (Attribute-Based Access Control)** принимает решение на основе **атрибутов** четырёх типов:
| Критерий | RBAC | ABAC |
|---|---|---|
| Основа решения | Роль пользователя | Множество атрибутов |
| Гибкость | Статичные роли | Динамические правила |
| Сложность | Простой в реализации | Сложнее, нужен policy engine |
| Масштабируемость | Role explosion при сложных правилах | Хорошо масштабируется |
| Аудит | Просто: кто в какой роли | Сложнее: нужно анализировать policies |
| Когда использовать | Простые иерархии (admin/editor/viewer) | Контекстные правила (время, место, владелец) |
**На практике RBAC и ABAC комбинируют.** Базовые роли через RBAC (admin/user), тонкие правила - через ABAC (пользователь редактирует только свои посты). Этот подход называется **Policy-Based Access Control (PBAC)**. OPA (Open Policy Agent) - стандарт де-факто для policy-as-code.
Инструменты для ABAC: **OPA (Open Policy Agent)** - политики пишутся на языке Rego и проверяются как unit-тесты. AWS IAM - тоже ABAC под капотом: `aws:SourceIp`, `aws:CurrentTime` - атрибуты контекста.
В медицинской системе HIPAA требует, чтобы врач видел только записи своих пациентов. В RBAC для этого пришлось бы создавать роль `doctor-of-patient-X` для каждого пациента - абсурд. ABAC решает одной политикой: `subject.patients.includes(resource.ownerId)`. Один паттерн вместо тысяч ролей.
RBAC достаточно для любой системы - нужно просто создать правильный набор ролей
RBAC работает для статических иерархий. Для контекстных правил (врач видит только своих пациентов, менеджер утверждает бюджет до определённой суммы, доступ только из офиса) нужен ABAC или RBAC + ABAC
RBAC привязывает права к ролям, а не к данным. Чтобы выразить «врач видит только своих пациентов» в RBAC, пришлось бы создавать роль для каждой пары врач-пациент - role explosion. ABAC решает через атрибуты: одна политика вместо тысяч ролей.
В системе правило: «Менеджер может утвердить бюджет до 10 000; свыше - только директор». Какой подход реализует это корректно?
Ключевые идеи
- **Аутентификация (AuthN)** - «кто?» Три фактора: знание, владение, биометрия. MFA = 2+ разных категории. История Мэта Хонана - один фактор = один провал
- **Пароли:** только bcrypt/Argon2. НИКОГДА plain text, MD5, SHA-256. Разница в скорости перебора - в миллион раз
- **Авторизация (AuthZ)** - «что можно?» 401 = не аутентифицирован, 403 = не авторизован. JWT в httpOnly cookie, НЕ localStorage
- **RBAC** - роли с разрешениями, иерархическое наследование. Просто, но ведёт к role explosion при сложных правилах
- **ABAC** - решения на атрибутах (кто, что, как, контекст). Гибко, масштабируемо, комбинируйте с RBAC
Связанные темы
Аутентификация и авторизация - контрмеры для STRIDE-категорий Spoofing и Elevation of Privilege:
- Модели угроз и STRIDE — AuthN защищает от Spoofing, AuthZ - от Elevation of Privilege
- Криптография — Как работают bcrypt, JWT-подписи и TLS под капотом
- Что такое информационная безопасность — AuthN/AuthZ реализуют Confidentiality из CIA Triad
Вопросы для размышления
- Какой алгоритм хеширования используется для паролей в текущем проекте? Если неизвестно - самое время проверить.
- Сколько уровней авторизации есть в приложении? Хватает ли RBAC, или уже появились edge-cases, где нужен ABAC?
- Представьте, что JWT-secret утёк. Что произойдёт и как это исправить?
Связанные уроки
- sec-01 — CIA Triad - основа, на которой строится AuthN/AuthZ
- sec-02 — STRIDE: AuthN защищает от Spoofing, AuthZ - от Elevation of Privilege
- sec-04 — Session management и JWT - следующий шаг после AuthN/AuthZ
- devops-05 — RBAC реализуется в Kubernetes через ServiceAccount и ClusterRole
- cloud-03 — AWS IAM - ABAC под капотом с атрибутами SourceIp и CurrentTime
- web-05 — OAuth 2.0 flow для делегированной авторизации в веб-приложениях
- ds-11 — Distributed identity management - те же принципы на масштабе микросервисов
- net-68-auth-network