atak na potok CI/CD
| Po angielsku | CI/CD pipeline compromise |
|---|---|
| Którą formą pisać | obie formy Obie formy są w obiegu. Przy pierwszym wystąpieniu pisz „polski termin (english term)”, dalej sam polski. |
| Inne formy | atak na pipeline CI/CD · kompromitacja pipeline’u CI/CD · przejęcie GitHub Actions |
| Kategoria | Chmura, kontenery i łańcuch dostaw |
Atak na potok CI/CD (CI/CD pipeline compromise) to przejęcie zautomatyzowanego procesu budowania, testowania i wdrażania oprogramowania, na przykład przepływu pracy w GitHub Actions. Celem jest wstrzyknięcie złośliwego kodu do wydawanej wersji albo kradzież sekretów: kluczy do chmury, tokenów i haseł do baz. OWASP zauważa, że atakujący traktują usługi CI/CD jako skuteczną drogę do najcenniejszych zasobów organizacji [1]. Jest to jedna z form ataku na łańcuch dostaw (supply chain attack), bo skażona wersja trafia do wszystkich odbiorców.
Jak działa
Potok CI/CD uruchamia kod z repozytorium na maszynie wykonawczej, która ma dostęp do sekretów i uprawnienia do publikacji. Kto zmusi potok do wykonania własnych poleceń, dziedziczy te uprawnienia. OWASP nazywa to zatruciem wykonania potoku (Poisoned Pipeline Execution, CICD-SEC-4) [1].
Najczęstsze wejścia to:
- Wstrzyknięcie przez dane wejściowe. Dokumentacja GitHub ostrzega, że niezaufanych danych, takich jak tytuł zgłoszenia czy nazwa gałęzi, nie wolno wstawiać wprost do generowanego skryptu powłoki; należy przekazywać je jako argumenty akcji albo przez zmienne środowiskowe [2]. To odmiana wstrzyknięcia poleceń (command injection).
- Uprzywilejowane wyzwalacze. Wyzwalacz
pull_request_targetdziała w kontekście uprzywilejowanym i dzieli pamięć podręczną gałęzi głównej, więc pobranie w nim niezaufanego kodu jest groźne [2]. - Skażona zależność. Akcja albo biblioteka zewnętrzna może zostać przejęta u źródła; OWASP opisuje to jako nadużycie łańcucha zależności (CICD-SEC-3) [1].
- Przejęte konto. Wykradzione dane uwierzytelniające osoby z prawem zapisu wystarczą do zmiany przepływu pracy.
Przebieg ataku z wstrzyknięciem przez nazwę gałęzi, wzorowany na incydencie Ultralytics, pokazuje schemat poniżej.
Rodzaje ryzyk
OWASP wyróżnia dziesięć ryzyk bezpieczeństwa CI/CD [1]. Najważniejsze dla typowego zespołu zestawia tabela.
| Identyfikator | Ryzyko | Przykład skutku |
|---|---|---|
| CICD-SEC-1 | niewystarczająca kontrola przepływu [1] | kod trafia na produkcję bez przeglądu |
| CICD-SEC-3 | nadużycie łańcucha zależności [1] | złośliwy pakiet w buildzie, zob. dependency confusion (podmiana zależności) |
| CICD-SEC-4 | zatrute wykonanie potoku [1] | polecenia atakującego na maszynie CI |
| CICD-SEC-6 | słaba higiena poświadczeń [1] | sekrety w logach lub w kodzie |
| CICD-SEC-9 | brak weryfikacji integralności artefaktów [1] | podmieniony plik wydania |
Pozostałe pozycje listy to m.in. niewystarczające zarządzanie tożsamością i dostępem, niebezpieczna konfiguracja systemu, niekontrolowane usługi zewnętrzne oraz brak logowania i widoczności [1].
W WordPressie
Wtyczki i motywy z katalogu WordPress.org są wydawane przez oznaczenie nowej wersji w repozytorium SVN. Część autorów automatyzuje ten krok z GitHuba, więc token do SVN albo hasło konta trafia do sekretów potoku. Przejęcie takiego potoku lub konta oznacza, że skażona aktualizacja dotrze do wszystkich stron z włączoną automatyczną aktualizacją.
Ryzyko nie jest teoretyczne. W dniach 23–24 czerwca 2024 roku atakujący przejęli pięć kont WordPress.org metodą credential stuffing, czyli hasłami z wycieków z innych serwisów, i wydali złośliwe aktualizacje pięciu wtyczek [7]. Zespół wtyczek zalecił wtedy unikalne hasła, uwierzytelnianie dwuskładnikowe (2FA), ograniczenie dostępu do aktywnych programistów i włączenie potwierdzania wydań [7].
Potwierdzanie wydań (Release Confirmation) wymaga, by po oznaczeniu wersji w SVN ktoś z autorów zatwierdził ją w panelu zarządzania wydaniami [8]. Funkcja jest opcjonalna i wystarczy jedno potwierdzenie [8], ale sam token wykradziony z potoku nie wystarczy już do publikacji.
Drugi przypadek to strony wdrażane automatycznie z repozytorium na serwer, na przykład przez SFTP lub rsync. Sekret wdrożeniowy w potoku daje wtedy zapis do plików produkcyjnych, czyli możliwość wgrania tylnej furtki (backdoor).
Zagrożenia i skutki
- Kradzież sekretów. W incydencie tj-actions/changed-files złośliwy kod ujawniał w logach akcji m.in. klucze dostępowe, tokeny GitHub PAT, tokeny npm i prywatne klucze RSA [3].
- Skażone wydania. Użytkownicy instalują złośliwą wersję z zaufanego źródła, często automatycznie.
- Nadużycie zasobów. W przypadku Ultralytics ładunkiem była koparka kryptowalut [5], czyli cryptojacking u odbiorców.
- Dostęp do infrastruktury. Przejęte klucze chmurowe prowadzą dalej niż sam potok.
Jak się bronić
CISA i NSA opublikowały 28 czerwca 2023 roku wspólne wytyczne z zaleceniami wzmacniania potoków CI/CD [4]. Dokumentacja GitHub dodaje konkretne reguły [2]:
- przypinać akcje do pełnego skrótu commita, bo to jedyny sposób na niezmienne wydanie akcji [2];
- ustawić domyślne uprawnienia tokenu
GITHUB_TOKENna odczyt i podnosić je tylko w konkretnych zadaniach [2], zgodnie z zasadą najmniejszych uprawnień; - zamiast długowiecznych kluczy w sekretach używać OpenID Connect i krótkotrwałych tokenów [2];
- okresowo prowadzić rotację kluczy i sprawdzać, jak sekrety są używane [2]; zob. też zarządzanie sekretami.
Przykład ustawień obronnych w pliku przepływu pracy:
permissions:
contents: read
steps:
- uses: actions/checkout@<pełny-skrót-commita>
Po podejrzeniu naruszenia CISA zaleca natychmiastową rotację wszystkich ujawnionych sekretów, bo należy je uznać za skompromitowane [3]. Security Bez Tabu zaleca ponadto przegląd logów przepływów pod kątem podejrzanych połączeń wychodzących i monitorowanie nietypowych zmian tagów i referencji w repozytorium [6]. Integralność wydań wspiera podpisywanie kodu (code signing).
Historia i przykłady
- Ultralytics, grudzień 2024. Wersje 8.3.41, 8.3.42, 8.3.45 i 8.3.46 biblioteki Python zawierały koparkę XMRig; atakujący wykorzystał wyrażenia w przepływie GitHub Actions kontrolowane przez użytkownika i nazwę gałęzi z poleceniami powłoki [5].
- tj-actions/changed-files, marzec 2025. CISA opisała przejęcie akcji w dniach 12–15 marca 2025 roku, powiązane z wcześniejszym przejęciem reviewdog/action-setup 11 marca; oba przypadki otrzymały numery CVE-2025-30066 i CVE-2025-30154 [3].
- Trivy, marzec 2026. Security Bez Tabu opisał przejęcie akcji
aquasecurity/trivy-actioniaquasecurity/setup-trivy: napastnik przepisał większość tagów wersji tak, by wskazywały złośliwe rewizje, co pozwoliło kraść sekrety bez zmiany konfiguracji potoków ofiar [6]. Wniosek autorów: tag wersji nie gwarantuje niezmienności [6].
Przypisy
8- [1] OWASP Top 10 CI/CD Security Risks · OWASP
- [2] Security hardening for GitHub Actions · GitHub Docs
- [3] Supply Chain Compromise of Third-Party tj-actions/changed-files (CVE-2025-30066) and reviewdog/action-setup@v1 (CVE-2025-30154) · CISA
- [4] CISA and NSA Release Joint Guidance on Defending Continuous Integration/Continuous Delivery (CI/CD) Environments · CISA
- [5] Zarabianie kryptowalut za pomocą GitHub Actions – jak wykorzystano atak na łańcuch dostaw do przejęcia biblioteki Python Ultralytics · Sekurak
- [6] Naruszenie Trivy GitHub Actions: przejęte tagi umożliwiły kradzież sekretów CI/CD · Security Bez Tabu
- [7] Keeping Your Plugin Committer Accounts Secure · WordPress.org
- [8] Release Confirmation Emails — Plugin Handbook · WordPress.org
Hasła w tym artykule
14- atak na łańcuch dostaw
- wstrzyknięcie poleceń (command injection)
- dane uwierzytelniające
- dependency confusion (podmiana zależności)
- automatyczna aktualizacja
- credential stuffing
- uwierzytelnianie dwuskładnikowe
- SFTP
- tylna furtka
- cryptojacking
- zasada najmniejszych uprawnień
- rotacja kluczy
- zarządzanie sekretami
- podpisywanie kodu