
Co znajdziesz w tym artykule?
Wprowadzenie do problemu / definicja
Bezpieczeństwo pipeline’ów CI/CD coraz częściej zależy nie od pojedynczej podatności, lecz od sposobu, w jaki łączą się ze sobą pozornie poprawne mechanizmy automatyzacji. W przypadku GitHub Actions problem pojawia się wtedy, gdy dane kontrolowane przez nieuprzywilejowanego użytkownika trafiają ostatecznie do workflow działającego z wyższymi uprawnieniami.
To właśnie taka błędna kompozycja zdarzeń, artefaktów i tokenów może prowadzić do eskalacji uprawnień, mimo że każdy osobny plik YAML wygląda poprawnie. W efekcie tradycyjne skanery bezpieczeństwa dla CI/CD mogą nie wychwycić realnego wektora ataku.
W skrócie
Nowy wzorzec ataku na GitHub Actions opiera się na naruszeniu granic zaufania między workflow o różnym poziomie uprawnień. Szczególnie ryzykowne są zdarzenia takie jak pull_request_target oraz workflow_run, które mogą działać w kontekście repozytorium bazowego i uzyskiwać dostęp do sekretów lub tokenów z szerszym zakresem uprawnień.
- atakujący dostarcza nieufne dane przez pull request, komentarz, nazwę gałęzi lub artefakt,
- mniej uprzywilejowany workflow przetwarza te dane i przekazuje je dalej,
- bardziej uprzywilejowany workflow wykonuje je lub wykorzystuje w zaufanym kontekście,
- skanery nie wykrywają problemu, bo analizują pojedyncze pliki zamiast pełnego przepływu danych.
Kontekst / historia
Temat zyskał rozgłos po opisaniu klasy ryzyka określanej jako Cordyceps. Badacze wskazali, że problem nie dotyczy jednej konkretnej luki w produkcie, lecz architektury pipeline’ów budowanych z wielu zależnych od siebie workflow.
To ważna zmiana perspektywy. Zamiast pytać, czy pojedynczy workflow zawiera oczywisty błąd, trzeba ocenić, czy cały łańcuch automatyzacji nie pozwala na przejście nieufnych danych do uprzywilejowanego środowiska. Ryzyko dodatkowo rośnie wraz z kopiowaniem gotowych szablonów i generowaniem konfiguracji CI/CD przez narzędzia AI.
Analiza techniczna
Technicznie opisywany atak składa się z kilku etapów. Pierwszym jest dostarczenie danych kontrolowanych przez napastnika. Mogą to być między innymi tytuł pull requestu, treść komentarza, nazwa branchu, metadane zdarzenia albo zawartość artefaktu wygenerowanego przez wcześniejszy workflow.
Następnie takie dane są używane w niebezpieczny sposób. Typowy scenariusz obejmuje interpolację wejścia użytkownika bez odpowiedniego cytowania do kroku run, co może skutkować wstrzyknięciem poleceń powłoki. Inną możliwością jest przekazanie danych do skryptów wykonujących logikę dynamiczną, na przykład w JavaScript, gdzie również może dojść do wykonania nieautoryzowanego kodu.
Najgroźniejszy etap następuje wtedy, gdy mniej uprzywilejowany workflow zapisuje kontrolowane dane do artefaktu, outputu lub innego kanału wymiany stanu, a następnie drugi workflow odczytuje te dane już w kontekście z dostępem do sekretów, tokenów lub uprawnień zapisu do repozytorium. Właśnie ta zależność między workflow sprawia, że klasyczne narzędzia skanujące często nie rozpoznają zagrożenia.
Szczególną ostrożność trzeba zachować przy zdarzeniach pull_request, pull_request_target i workflow_run. Standardowe pull_request działa zazwyczaj w bardziej ograniczonym kontekście, natomiast pull_request_target uruchamia workflow w kontekście repozytorium bazowego. Jeśli taki workflow pobierze kod z gałęzi atakującego lub zaufa niezweryfikowanym danym wejściowym, skutkiem może być przejęcie sekretów albo nadużycie tokenu GITHUB_TOKEN.
Konsekwencje / ryzyko
Skutki udanego ataku mogą wykraczać daleko poza pojedynczy build. Napastnik może uzyskać możliwość modyfikacji repozytorium, zmiany workflow, kradzieży sekretów środowiskowych, tokenów chmurowych lub poświadczeń używanych w procesie wydawniczym.
W bardziej krytycznych scenariuszach prowadzi to do kompromitacji łańcucha dostaw oprogramowania. Atakujący może wpłynąć na proces budowania pakietów, obrazów kontenerowych, reguł bezpieczeństwa czy komponentów wykorzystywanych przez inne zespoły. Szczególnie niebezpieczne jest to, że build może nadal kończyć się sukcesem, a standardowe wskaźniki jakości nie pokażą żadnej anomalii.
- kradzież sekretów i tokenów,
- nieautoryzowany zapis do repozytorium,
- modyfikacja pipeline’ów CI/CD,
- publikacja złośliwych artefaktów jako zaufanych aktualizacji,
- rozprzestrzenienie kompromitacji na zależne projekty.
Rekomendacje
Aby ograniczyć ryzyko, organizacje powinny traktować GitHub Actions jako środowisko wymagające wyraźnego modelowania granic zaufania. Kluczowe znaczenie ma nie tylko bezpieczna składnia workflow, ale też kontrola przepływu danych między zdarzeniami i poziomami uprawnień.
- preferować
pull_requestzamiastpull_request_targetdla nieufnych wkładów z forków, - nie wykonywać checkoutu kodu z pull requestu w uprzywilejowanych workflow,
- unikać bezpośredniej interpolacji danych wejściowych do kroków
run, - traktować wszystkie dane ze zdarzeń GitHub jako niezaufane i poddawać je walidacji,
- ograniczać uprawnienia
GITHUB_TOKENzgodnie z zasadą najmniejszych uprawnień, - jawnie definiować sekcję
permissionsw każdym workflow, - przypinać akcje firm trzecich do konkretnych commit SHA,
- stosować dodatkowe bramki bezpieczeństwa dla uprzywilejowanych workflow,
- analizować artefakty, outputy i zależności między workflow, a nie tylko pojedyncze pliki YAML.
Podsumowanie
Przypadek GitHub Actions i wzorca Cordyceps pokazuje, że zielony wynik skanera nie musi oznaczać bezpiecznego pipeline’u. Największe ryzyko pojawia się tam, gdzie nieufne dane mogą przejść do uprzywilejowanego kontekstu przez złożony, lecz pozornie poprawny łańcuch workflow.
Dla zespołów bezpieczeństwa oznacza to konieczność przejścia od analizy lokalnych antywzorców do oceny pełnych przepływów danych, uprawnień i relacji między procesami automatyzacji. W świecie rosnącej automatyzacji DevSecOps to właśnie taka analiza kompozycyjna staje się jednym z najważniejszych elementów ochrony łańcucha dostaw oprogramowania.