open atlas
↑ К треку
Основы безопасности SECF · 05 · 03

Минимальные привилегии на практике

Минимальные привилегии — принцип, который все цитируют и почти никто не удерживает. Деградация — это расползание прав: гранты копятся, ничего не отзывается. Лекарство операционное: deny by default, доступ точно вовремя и цикл отзыва.

SECF Middle ◷ 15 min
Уровень
ОсновыJuniorMiddleSenior

Ты открываешь IAM-политику, привязанную к главной сервисной роли твоей команды, чтобы отладить ошибку прав, — и вот оно: s3:* на Resource: "*". Никто не решал, что биллинговый воркер должен уметь удалить любой бакет в аккаунте — оно просто так получилось. Полтора года назад кому-то понадобился доступ на чтение к одному бакету, он упёрся в deny, нашлёпал на него wildcard, чтобы разблокировать релиз, и пошёл дальше. Грант пережил и задачу, и человека, и причину. Теперь эта роль в одной утёкшей утечке ключа от того, чтобы стереть боевое хранилище, — и самое страшное, что всё работает идеально. Минимальные привилегии не упали с грохотом. Они истёрлись, один удобный грант за раз.

К концу этого урока ты поймёшь, почему минимальные привилегии деградируют в избыточные, и три операционных хода — deny by default, доступ точно вовремя и цикл отзыва, — которые на самом деле удерживают линию.

Принцип — и почему его недостаточно просто провозгласить

Принцип минимальных привилегий гласит: каждый субъект — пользователь, сервис, процесс — должен держать ровно те права, что нужны ему для работы, и ни одним больше. NIST называет его фундаментом управления доступом; OWASP Authorization Cheat Sheet открывается словами «enforce least privileges» и «deny by default». Каждый инженер согласно кивает. Почти ни в одной боевой системе этого на самом деле нет.

Причина в том, что минимальные привилегии — это не свойство, которое настраивают один раз, а свойство, которое приходится поддерживать против постоянного давления. Права липки в одну сторону. Выдать легко: кто-то заблокирован, ты добавляешь allow, тикет закрывается, сегодня все довольны. Отозвать тяжело: тебя никто не блокирует правом, которое у тебя всё ещё есть, поэтому нет тяги его убрать, нет красного теста, нет алерта с пейджера. Система, которая выдаёт по запросу и никогда не отзывает, не дрейфует к минимальным привилегиям — она монотонно дрейфует от них. Вся проблема в этой асимметрии, и у неё есть имя.

Расползание прав: медленная течь

Расползание прав (privilege creep) — это постепенное накопление прав, которые субъекту больше не нужны. Оно приходит из горстки совершенно будничных источников, ни один из которых в момент не ощущается как решение по безопасности:

  • Смена роли, которая добавляет, не вычитая. Инженер переходит из команды платежей в платформу. Доступ группы платформы он получает в первый же день. А доступ к платежам? Он всё ещё на месте через год — никто не владеет вычитанием, а отозвать его может что-то сломать, поэтому он остаётся.
  • Удобный wildcard. deny блокирует релиз в 16:00. Уезжает в прод фикс s3:* / Resource: *, потому что сузить его до трёх реально нужных действий и одного бакета — это двадцать минут, которых у тебя нет. Wildcard постоянен; дедлайн был временным.
  • Постоянный админ. Break-glass-доступ для инцидента в 2 ночи так и не отзывают на следующее утро. Теперь это просто «доступ, который у меня есть», а через три месяца он несущий для какой-то рутинной задачи, для которой никогда не предназначался.
  • Скопированная роль. Новому сервису нужны права? Клонируй роль у соседнего сервиса. Теперь он наследует каждый грант, который тот сервис нарастил, включая те, которые никто не может объяснить.

Каждый шаг локально рационален и глобально разъедающ. В итоге — флот идентичностей, каждая из которых держит куда больше власти, чем требует её реальная работа, а значит, радиус поражения любой одной скомпрометированной учётки огромен и полностью невидим до того дня, когда его эксплуатируют.

Deny by default: сделать «нет» точкой старта

Структурный фикс расползания начинается с фундамента — deny by default. Авторизация начинается с отказа, а доступ выдаётся только явным положительным правилом, совпадающим по субъекту, действию и ресурсу. Всё, что не разрешено явно, — запрещено, включая, что критично, всё новое.

Это звучит очевидно, пока не сопоставишь это со сбоем, который оно предотвращает. Система allow-by-default (или любой allowlist с wildcard-фолбэком) отказывает «открыто» (fails open): добавь новый эндпоинт, новый тип ресурса, новое админ-действие — и оно достижимо, если кто-то не вспомнил написать для него deny-правило. Deny by default отказывает «закрыто» (fails closed): новая штука недостижима, пока кто-то не напишет allow. Разница в том, утекает ли забытое правило в доступ или просто выдаёт 403, по которому кто-то заводит тикет. Fail-closed превращает твои упущения в неудобства, а не в пробои.

На практике это значит: никаких Resource: "*" и никаких action: * в политиках, где их можно избежать; права, ограниченные конкретными действиями на конкретных ресурсах; и ответ по умолчанию на «может ли эта идентичность сделать эту штуку» — нет, пока правило не скажет да. Цена реальна — ты пишешь больше узких правил и ешь больше 403 во время разработки. Эта цена и есть смысл. Это и есть то трение, что держит wildcard снаружи.

Почему это работает

Почему не аудитить права раз в квартал и не вычищать избыток? Потому что периодический аудит борется с асимметрией, которую не может выиграть. Гранты накапливаются непрерывно — каждый день, под реальными дедлайнами, — а вычистка происходит пакетом четыре раза в год и не является ничьей любимой работой. Хуже того, нельзя безопасно убрать право, про которое нельзя доказать, что оно не используется, а доказать отрицание («ничто на это не опирается») по живой системе по-настоящему трудно, поэтому аудиты склоняются к тому, чтобы оставлять. Аудит не бесполезен, но это швабра, а не кран. Устойчивый фикс меняет то, как гранты выдаются — короткоживущими и самоистекающими, — чтобы избыток вовсе не накапливался.

Доступ точно вовремя: гранты, которые истекают сами

Асимметрия, которая гонит расползание, — это «легко выдать, тяжело отозвать». Доступ точно вовремя (JIT, just-in-time) атакует её напрямую, делая отзыв автоматическим: вместо того чтобы держать постоянное право вечно, субъект запрашивает повышенный доступ под конкретную задачу, получает его на ограниченное окно, и система забирает его назад, когда окно закрывается, — никому не приходится помнить.

Паттерн всплывает на каждом слое:

  • Люди-админы: постоянное членство в роли администратора убирается; инженер запрашивает повышение (часто с причиной и согласованием) и получает его, скажем, на 60 минут, после чего членство в роли автоматически снимается. Состояние по умолчанию каждого человека — не привилегированное.
  • Сервисы: вместо долгоживущего API-ключа с широким scope, зашитого в деплой, нагрузка ассумит роль и получает короткоживущие учётки (минуты — час), которые авто-ротируются и авто-истекают. Утёкшая учётка полезна только внутри своего крошечного окна.
  • Break-glass: аварийный доступ сам является JIT-грантом — явно запрашивается, ограничен по времени, громко логируется и авто-отзывается, — поэтому инцидент в 2 ночи не оставляет за собой постоянный админ-грант.

JIT переворачивает устойчивое состояние. С постоянным доступом по умолчанию «у всех больше, чем нужно, всё время», и ты тратишь усилия на удаление избытка, который никогда полностью не выловишь. С JIT по умолчанию «ни у кого ничего нет, пока он не попросит», и привилегия существует только те минуты, что реально используется. Ты больше не борешься с расползанием уборкой — ты убрал поверхность, на которой расползание накапливается.

Выбери лучший вариант

У сервисной роли стоит `s3:*` на `Resource: *`, потому что кто-то добавил wildcard 18 месяцев назад, чтобы разблокировать релиз. Сервис на деле когда-либо вызывает только GetObject и PutObject на одном бакете. Какой фикс правильный?

Как зрелые инженеры удерживают линию

Удержание минимальных привилегий — это операционный цикл, а не разовая настройка. Зрелые ходы: сделать deny дефолтом, чтобы новая поверхность отказывала закрыто; делать гранты узкими (конкретные действия на конкретных ресурсах, без рефлекторных wildcard) и короткоживущими (JIT с жёстким истечением), чтобы привилегия существовала только пока используется; и замкнуть цикл отзывом — когда кто-то меняет команду, когда проект заканчивается, когда срабатывает break-glass, вычитанием должен кто-то владеть, а не оставлять его квартальному аудиту, который склоняется к тому, чтобы оставлять. Грант без истечения и без владельца — это тот самый, что станет инцидентом s3:* в следующем году.

Викторина

Почему расползание прав почти всегда заставляет права со временем расти, а не сжиматься, даже в хорошо организованных командах?

Викторина

В чём ключевое преимущество по безопасности у доступа точно вовремя перед постоянным админ-грантом?

Расставь шаги по порядку

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

  1. 1 Понаблюдать, какие действия/ресурсы роль реально использует (логи доступа / IAM access analyzer)
  2. 2 Написать новую политику, ограниченную ровно этими наблюдёнными действиями на этих конкретных ресурсах
  3. 3 Выкатить суженную политику и следить за deny-ошибками / 403 в staging и канарейке
  4. 4 Заменить долгоживущий ключ на короткоживущие assumed-role учётки
  5. 5 Добавить владельца и дату истечения/пересмотра, чтобы грант не стал тихо снова постоянным
Вспомните перед уходом
  1. 01
    Объясни, почему минимальные привилегии со временем истираются в избыточные, и назови механизм.
  2. 02
    Что именно чинят deny-by-default и доступ точно вовремя, и почему JIT — более устойчивое лекарство?
Итог

Минимальные привилегии — это принцип, который все цитируют и почти никто не удерживает, потому что это не настройка, которую конфигурируют один раз, а свойство, которое поддерживают против постоянного давления. Выдачу тянет реальный, немедленный блокер; у отзыва нет такой же тяги, поэтому права монотонно дрейфуют вверх. Эта деградация и есть расползание прав, питаемое сменами ролей, что добавляют не вычитая, удобными wildcard, отгруженными ради дедлайна, неотозванным break-glass и скопированными ролями. У операционного лекарства три хода. Deny by default делает так, что авторизация начинается с «нет», поэтому новая поверхность отказывает закрыто — забытое правило даёт 403, а не пробой. Узкие, короткоживущие гранты ограничивают права конкретными действиями на конкретных ресурсах. А доступ точно вовремя делает отзыв автоматическим: повышение запрашивается под задачу, держится на ограниченное окно и снимается, когда оно закрывается, поэтому состояние по умолчанию каждой идентичности непривилегированное, а утёкшая учётка ничего не стоит через минуты. Теперь, когда ты видишь s3:* на Resource: *, твой первый вопрос: кто владеет вычитанием, и когда этот грант истекает?

Практика

Начни сверху. Задачи идут от простого к сложному: вспомнить факт, применить к случаю, затем senior-уровень. Открой, попробуй, потом открой ответ.

вспомнитьприменитьуглубить0 из 6 завершено
Связанные уроки

Что-то непонятно?

Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.

Примени это

Примени этот урок в реальном проекте.

Лаборатория харденинга облакаВозьми облачный аккаунт, которым владеешь сам, и проведи его от состояния «работает» к состоянию «защищаемо». Ты измеришь реальную текущую posture, ужмёшь IAM до least privilege, не сломав приложение, закроешь сеть и секреты и докажешь каждое изменение диффом «до/после». Это и есть суть работы по облачной безопасности: не добавлять фичи, а убирать постоянный доступ и тихие мисконфигурации, которыми воспользовался бы атакующий.Моделирование угроз и закаливание небольшого приложенияВозьми небольшое приложение, которым ты полностью владеешь, и прогони его через цикл, в котором живёт настоящий инженер по безопасности: сначала разберись, как атакующий реально его сломает, а затем закрой эти пути один за другим. Ты построишь дерево атаки против собственного сервиса, а потом починишь аутентификацию, авторизацию, обращение с секретами, заголовки безопасности и валидацию ввода — и запишешь, какое исправление убивает какую ветку дерева. Это и есть всё ремесло защитной безопасности в миниатюре: не чек-лист, а цепочка от угрозы к мере, которую ты сможешь защитить вслух.
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources2
expand
  1. 01
  2. 02

Trademarks belong to their respective owners. Editorial reference only.