Что произошло#
Packagist призывает PHP-проекты обновить Composer после того, как изменение формата GitHub token привело к тому, что некоторые GitHub Actions tokens оказались раскрыты в CI logs.
Проблема затрагивает версии Composer до недавно выпущенных исправлений. Packagist сообщает, что Composer 2.9.8, 2.2.28 LTS и 1.10.28 устраняют проблему. Уязвимое поведение возникало, когда Composer отклонял значение, выданное GitHub Actions, или GitHub App installation token во время validation, а затем выводил полное значение token в stderr.
Триггером был не классический инцидент с malicious package. Это был сбой совместимости между логикой token validation в Composer и внедрением GitHub нового формата token. GitHub объявил 24 апреля, что новые GitHub App installation tokens перейдут на более длинный формат переменной длины. Развертывание должно было начаться 27 апреля и продолжаться в течение следующих недель.
Одна деталь оказалась критичной: новый формат включал дефис. Предыдущий validation regex в Composer не разрешал этот символ. Когда workflow передавал один из таких новых tokens, Composer мог отклонить его как invalid. В некоторых случаях итоговый error output мог включать сам token.
Именно это и является чувствительной частью. CI logs часто проще получить, чем доступ к secret stores. Их копируют, индексируют, хранят и просматривают больше людей и инструментов. Token, напечатанный в logs, уже не просто environment secret. Он становится artifact.
Кто подвержен риску#
Основной риск касается PHP-проектов, которые запускают Composer внутри GitHub Actions, особенно workflows, где Composer authentication настраивается с помощью GitHub-provided tokens или GitHub App installation tokens.
Packagist сообщает, что проблема может возникать в распространенных конфигурациях GitHub Actions, включая workflows, где setup actions регистрируют authentication в Composer. Исходные материалы не указывают единственный универсальный workflow pattern, который гарантированно приводит к exposure. Условие, на которое нужно смотреть, уже: Composer запускается в Actions, получает token в новом формате, не проходит validation и выводит это значение в stderr.
По словам сооснователя Packagist Нильса Адерманна, GitHub с тех пор откатил изменение формата token. Это снижает немедленную вероятность новых leaks, вызванных этим rollout. Но это не означает, что проблему можно безопасно игнорировать.
В обновлении Packagist от 13 мая сказано, что немедленно отключать GitHub Actions больше не требуется. Rollback дает экосистеме время обновить Composer до того, как GitHub предпримет новую попытку rollout формата token. GitHub также изучает улучшения secrets masking, которые могут снизить вероятность того, что случайно напечатанные credentials останутся видимыми в logs.
Тем не менее практическое окно exposure зависит от типа token и конфигурации runner.
- Tokens на GitHub-hosted runners обычно истекают после завершения job или максимум через 6 часов.
- Для self-hosted runners leaked token может оставаться valid до 24 часов после выдачи.
- GitHub App installation tokens могут иметь разные scopes, и их нужно проверять с учетом запрошенных permissions.
Согласно отчету, сам Packagist.org не затронут. Public registry не использует GitHub App и не запускает Composer с GitHub App installation tokens. Private Packagist уже применил исправление Composer и проверил update logs — exposure tokens не обнаружено.
Что изменилось в Composer#
Исправленные релизы Composer убирают отклоненное значение token из error message. Они также смягчают validation character set, чтобы Composer принимал новый формат GitHub token.
Командам следует немедленно обновиться до Composer 2.9.8 или Composer 2.2.28 LTS. Composer 1.10.28 также включает исправление для legacy users, хотя Packagist рекомендует по возможности переходить на Composer 2.x.
Это небольшое исправление code path с серьезными operational consequences. Failure mode заключался не в том, что Composer создал новый secret. Проблема была в том, что Composer обработал отклоненный secret так, будто это безопасный diagnostic text.
Такой паттерн встречается часто. Validation failures нередко создают подробные errors. Подробные errors полезны при разработке. Но в CI они могут превращаться в долговечные leaks.
Еще один важный момент — рекомендация GitHub: относитесь к tokens как к opaque strings. Не проверяйте их через hardcoded assumptions о длине, prefix или character set, если платформа явно не предоставляет стабильный contract для такой проверки. Форматы tokens меняются. Security tooling, build tooling и package managers должны fail closed, не печатая credential, который не прошел validation.
Что командам сделать сейчас#
Первое действие: обновить Composer в каждом workflow, где Composer запускается внутри GitHub Actions. Целевые версии — Composer 2.9.8 или 2.2.28 LTS. Если проект все еще на Composer 1.x, используйте 1.10.28 как срочное исправление, а затем запланируйте миграцию на Composer 2.x.
Практический checklist для maintainers:
- Найдите workflows, где вызываются
composer install,composer update,composer config,shivammathur/setup-phpили другие setup actions, которые могут настраивать Composer authentication. - Убедитесь, что CI действительно использует исправленную версию Composer, а не старый binary из base image, cache или preinstalled toolchain.
- Проверьте recent failed GitHub Actions runs за период rollout нового token format, особенно jobs, где Composer падал на authentication или validation.
- Если в logs найден полный token, считайте его скомпрометированным: удалите artifact/log там, где это возможно, отзовите или перевыпустите credential и проверьте activity по соответствующему GitHub App или repository.
- Для self-hosted runners проверьте более длинное окно риска: такие tokens могли оставаться valid до 24 часов после выдачи.
- Ограничьте
GITHUB_TOKENи GitHub App permissions до минимально необходимых scopes, чтобы случайная утечка имела меньший blast radius. - Добавьте правило в internal CI hygiene: tools не должны печатать rejected secrets в diagnostics, даже если значение кажется invalid.
Главный вывод: rollback GitHub уменьшил срочность, но не заменяет обновление Composer. Если Composer запускается в Actions, исправление нужно применить до следующей попытки изменения token format, а старые failed logs стоит проверить как потенциальный источник credential exposure.