Co się stanie, jak umieszczę sekret w kodzie?
Podczas tworzenia aplikacji wykorzystujemy często bardzo wiele różnych sekretów. Nieraz to jest nawet sekret w kodzie. W wielu przypadkach są to jakiegoś rodzaju klucze dostępowe do pewnych innych części naszego systemu jak:
- baza danych,
- inny serwis,
- kolejka wiadomości.
Może to być również klucz dostępu do zewnętrznych usług, które jednak operują na naszych wrażliwych danych
- dostawca usług płatności,
- CRM,
- system do generowania faktur.
W każdym z takich przypadków sekrety, których używamy w aplikacji, są kluczem do istotnych danych lub akcji. Dlatego też są bardzo ważne i należy je specjalnie chronić. Jednym z elementów zajmowania się takimi sekretami jest ich przechowywanie.
Życie sekretu w systemie
Całość cyklu życia sekretu w systemie opisałem w poście [???]. Jednak tu skupimy się na jednym z jego aspektów.
W jaki sposób sekrety zaczynają swoje życie w naszym systemie?
Weźmy na przykład Stripe — system do obsługi płatności. Żeby się z nim zintegrować, musimy w panelu admina wygenerować klucz do API i zacząć go używać w swoim systemie.
Wymagana jest tu ręczna praca konkretnej osoby.
Tylko kto ją wykona?
Dobra zasada w bezpieczeństwie aplikacji mówi, że deweloperzy nie powinni mieć dostępu do produkcyjnych sekretów. To dość rozsądne, ponieważ szczegółowa wiedza o tym, jak działa aplikacja oraz znajomość sekretów produkcyjnych, dawałaby im olbrzymią władzę.
Dlatego często to administratorzy lub DevOpsi konfigurują produkcyjne sekrety, ale nie zawsze. Są firmy, w których nie tylko deweloperzy mają pełen dostęp do Produkcji. Co więcej, również na środowiskach testowych są używane Produkcyjne sekrety.
To często prowokuje wklejenie takich, „niezmiennych” by się wydawało sekretów, bezpośrednio w repozytorium kodu. To bardzo wygodne i proste, ale czy bezpieczne?
Niestety nie.
Wyciek sekretu z repozytorium
Historia wielu firm pokazuje, że nawet gdy się staramy, to może nam się zdarzyć ujawnienie sekretów:
- przez przypadkowe opublikowanie naszego prywatnego repo,
- przez push na inny zdalny brach w repozytorium,
- przez brak ścisłej kontroli dostępu do repozytorium (zazwyczaj wszyscy programiści mają dostęp do kodu projektów).
Zobaczmy, jak to wygląda na świecie. Zerknijmy na raport state-of-secrets-sprawl-report-2024. Pokazano w nim, że liczba upublicznianych sekretów rośnie z roku na rok. W roku 2023 była to liczba 12 mln sekretów.
Okazuje się nawet, że 1 na 10 osób na GitHubie opublikowała kiedyś sekret w kodzie. To dość dużo. A 0,5% commitów zawiera sekret, czyli jeden na 200. Pomyśl, ile commitów jest w Twoim repozytorium każdego dnia?
Nawet gdy nasza aplikacja jest kuloodporna, to nadal sekret może się znaleźć w skrypcie PowerShellowym.
Czas do pierwszego wycieku
Okazuje się, że sekret upubliczniony w publicznym repozytorium jest często wykorzystywany już w ciągu godziny od upublicznienia. Musimy pamiętać, że w sieci cały czas działają boty, które przeczesują Internet w poszukiwaniu ciekawych kąsków. Takim właśnie kąskiem może być sekret w naszym kodzie. Szczególnie jak to jest sekret, który dużo potrafi.
Doskonale obrazuje to eksperyment przeprowadzony przez Cybenari. Sprawdzili oni, jak szybko zostanie wykorzystany klucz upubliczniony w konkretnym medium. Okazuje się, że od momentu upublicznienia go w npmjs potrzeba mniej niż minuty do pierwszego użycia. GitHub czy PyPI zresztą też nie wyglądają tu najlepiej. A teraz pomyśl sobie, ile czasu zajęłoby Ci wykasowanie takiego sekretu z repozytorium? Dla ułatwienia załóż, że odkryjesz fakt upublicznienia tuż po tym, jak to się stało.
Dlatego właśnie powinniśmy wykrywać sekrety w naszym kodzie i do nich nie dopuszczać. Na przykład, odpowiednio konfigurując pre-commit hooki dla naszego repozytorium git. Wtedy możemy zapewnić, że sekret nie znajdzie się w historii repetytorium, skąd dość trudno cokolwiek usunąć.
Możemy też skorzystać z narzędzi, które nam w tym pomogą:
Czy da się to zabezpieczyć wcześniej?
No pewnie. Już podczas Modelowania zagrożeń możemy przewidzieć użycie nowych sekretów w kodzie i być wyczulonym na te dane podczas dewelopmentu.
Działania po wycieku
A co zrobić, jeśli po fakcie znajdziemy jakiś sekret w repozytorium?
- jak najszybciej zrotujmy ten sekret,
- anulujmy poprzedni sekretu.
To podstawowe zasady. Jednak najlepsza porada, którą można tu podać to: myśl o sekretach już podczas projektowania i kodowania, żeby nie dopuścić do tego, żeby znalazły się w kodzie.