Zarządzanie sekretami w projektach IT
Dlaczego token w repozytorium to nie „drobny błąd".
Większość wycieków danych nie zaczyna się od zaawansowanego ataku. Zaczyna się od pliku .env wypchanego na GitHuba, klucza API w historii commitów albo hasła zakodowanego na stałe w skrypcie, który „tylko na chwilę” trafił do repozytorium. Ta „chwila” często trwa miesiącami.
Sekrety - tokeny, klucze API, hasła, certyfikaty, dane dostępowe do baz danych - to jedna z najczęściej pomijanych klas ryzyka w projektach IT. Nie dlatego, że ludzie nie wiedzą, że to problem. Dlatego, że pod presją czasu, przy wdrożeniu na produkcję o trzeciej w nocy albo podczas szybkiego prototypowania, te zasady idą na bok.
Jak wygląda problem w praktyce
GitHub regularnie skanuje publiczne repozytoria pod kątem wykrytych sekretów i wysyła powiadomienia do właścicieli kont. W 2023 roku wykrył i powiadomił o ponad 1 milionie tokenów. To tylko publiczne repozytoria - prywatne skanuje się rzadziej, a te w organizacjach często w ogóle.
Narzędzie takie jak truffleHog albo gitleaks potrafi w ciągu kilku minut przeszukać całą historię commitów repozytorium i wyciągnąć z niej tokeny, hasła czy ciągi znaków przypominające klucze. Atakujący robi dokładnie to samo. Co gorsza, usunięcie pliku z repozytorium nie usuwa go z historii - sekret wciąż tam jest, dostępny po prostym git log.
Osobna kategoria to repozytoria firm przejętych przez inne podmioty albo porzucone projekty open source. Kod żyje długo po tym, jak nikt już o nim nie myśli.
Czym jest sekret i gdzie się ukrywa
Sekret to każda wartość, która daje dostęp do zasobu i nie powinna być znana nikomu poza uprawnionym systemem lub osobą. W praktyce to:
- klucze API do zewnętrznych serwisów (AWS, Stripe, SendGrid, OpenAI),
- hasła do baz danych,
- tokeny JWT i klucze do ich podpisywania,
- prywatne klucze SSH i certyfikaty TLS,
- dane dostępowe do wewnętrznych systemów,
- zmienne środowiskowe z danymi uwierzytelniającymi.
Sekrety pojawiają się w miejscach, w których nikt ich nie szuka: w logach aplikacji, w metadanych obrazów Dockera, w plikach konfiguracyjnych commitowanych razem z kodem, w historii shella na serwerze, w eksportach bazy danych zostawionych na dysku.
Najczęstsze błędy
Plik .env w repozytorium. Klasyk. Plik tworzony lokalnie do konfiguracji środowiska deweloperskiego, który przez przypadek lub z braku odpowiedniego .gitignore trafia do repozytorium. Czasem prywatnego, czasem nie.
Hardcoding w kodzie źródłowym. Klucz API wpisany bezpośrednio w kodzie, bo „to tylko do testów”. Testy się kończą, kod zostaje.
Sekrety w zmiennych środowiskowych bez żadnej kontroli. Samo używanie zmiennych środowiskowych to dobra praktyka, ale jeśli nie ma żadnej kontroli nad tym, kto i skąd je czyta, problem pozostaje — tylko mniej widoczny.
Brak rotacji. Token wygenerowany dwa lata temu, używany nieprzerwanie, nigdy nieodwołany. Jeśli gdzieś wyciekł, atakujący ma cierpliwość.
Zbyt szerokie uprawnienia. Klucz do S3 z pełnym dostępem do wszystkich bucketów, bo „tak było łatwiej skonfigurować”. W przypadku wycieku oznacza to dostęp do wszystkiego, nie tylko do tego, czego potrzebuje aplikacja.
Jak to robić poprawnie
Vault i dedykowane systemy do zarządzania sekretami. HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, Google Secret Manager to narzędzia zaprojektowane właśnie do tego. Sekret nie trafia do kodu ani do zmiennych środowiskowych na serwerze; aplikacja pobiera go w momencie uruchomienia z centralnego miejsca, gdzie dostępy są kontrolowane i audytowane.
Zasada minimalnych uprawnień. Klucz API dla mikroserwisu odpowiedzialnego za wysyłkę e-maili powinien mieć dostęp wyłącznie do wysyłki e-maili. Nie do historii płatności, nie do bazy użytkowników, nie do niczego innego. To ogranicza zasięg szkód w przypadku wycieku.
Rotacja sekretów. Sekrety powinny mieć określony czas życia i być wymieniane regularnie. Niektóre systemy robią to automatycznie. To nie tylko dobra praktyka — w wielu regulacjach (SOC 2, ISO 27001) jest to wymóg.
Skanowanie przed wdrożeniem. gitleaks, truffleHog, detect-secrets — narzędzia tego typu można włączyć jako pre-commit hook albo krok w CI/CD. Sekret wykryty przed commitem nie trafia do historii.
Oddzielne sekrety dla każdego środowiska. Klucz do bazy deweloperskiej to nie ten sam klucz, co do produkcji. Brzmi oczywisto, ale w praktyce nagminnie się to miesza.
Co zrobić, gdy sekret już wyciekł
Pierwsza reakcja ma znaczenie. Jeśli klucz trafił do publicznego repozytorium, należy założyć, że został już przechwycony — boty skanujące GitHuba działają w czasie niemal rzeczywistym.
Kolejność działań:
- Odwołaj sekret natychmiast.
- Wygeneruj nowy.
- Zaktualizuj wszystkie miejsca, gdzie był używany.
- Przejrzyj logi pod kątem nieautoryzowanych operacji.
- Wyczyść historię repozytorium narzędziami typu
git filter-repo(niegit filter-branch, który jest przestarzały). - Jeśli wymagają tego przepisy lub umowy - poinformuj odpowiednie osoby.
Samo usunięcie pliku committem „ups, usuwam klucze” nie wystarczy.
Podsumowanie
Zarządzanie sekretami to nie zaawansowana dziedzina bezpieczeństwa zarezerwowana dla dużych organizacji. To podstawa higieny każdego projektu IT, niezależnie od tego, czy chodzi o startup z trzema mikroserwisami, czy o aplikację korporacyjną.
Większość incydentów związanych z wyciekiem sekretów nie jest efektem wyrafinowanego ataku. Jest efektem pośpiechu, braku nawyków i założenia, że „przecież to prywatne repozytorium”. Atakujący wiedzą o tym dokładnie tyle samo co Ty i liczą na to, że o tym zapomnisz.