~/guides/github-actions-permissions-pipeline-hijack

Git

Как неверные permissions в GitHub Actions позволяют захватить весь релизный пайплайн

Разбор паттерна атаки на AsyncAPI 14 июля 2026 года и как избежать той же ошибки в собственных workflow.

14 июля 2026 года атакующий скомпрометировал релизный пайплайн проекта AsyncAPI, не украв ни одного токена доступа. Вместо этого он воспользовался push-доступом в ветку репозитория и позволил легитимному CI сделать всю грязную работу самостоятельно — включая публикацию вредоносного пакета с валидной SLSA провенанс-атрибуцией.

Как технически работал захват

on:
  push:
    branches: [next]
permissions:
  contents: write
  id-token: write

Workflow, реагирующий на push в определённую ветку и обладающий правом на публикацию через OIDC (id-token: write), фактически даёт любому, кто получил push-доступ в эту ветку, возможность инициировать полноценный релиз от имени доверенной инфраструктуры проекта.

Почему провенанс-атрибуция не спасла

Атакующие пакеты несли легитимные SLSA provenance attestations — они честно доказывали, что пакет собран официальным workflow проекта. Провенанс подтверждает происхождение сборки, но не то, что триггерящий коммит был легитимным — если скомпрометирован сам процесс, доверенная подпись на выходе этого процесса ничего не значит.

Практический паттерн риска

Компонент Что делает риск реальным
Триггер, реагирующий на внешний ввод pull_request_target, push в ветку с широким доступом
Широкие permissions contents: write, id-token: write, packages: write
Отсутствие дополнительных проверок Нет ручного approval перед реальной публикацией

Именно сочетание всех трёх факторов создаёт реальную возможность захвата, а не каждый по отдельности.

Практическая защита

Принцип наименьших привилегий — каждый job должен запрашивать только те конкретные права, которые ему реально нужны, а не общий широкий набор permissions на уровне всего workflow. Для действительно критичных релизных пайплайнов разумно добавить ручной approval-шаг перед публикацией, даже если это немного замедляет процесс.

Как проверить собственные workflow на этот паттерн

GitHub Actions Workflow Permissions Batch Auditor проверяет сразу несколько workflow-файлов на именно эту комбинацию риска.

Итоговый чеклист

Захват пайплайна AsyncAPI произошёл без кражи токена — через push-доступ в ветку и избыточные permissions самого workflow.

SLSA provenance подтверждает, что сборку произвёл легитимный процесс, но не то, что запустивший его коммит был легитимным.

Принцип наименьших привилегий на уровне каждого job, а не общие широкие permissions на весь workflow, — практическая защита от этого паттерна атаки.