Preorder drugiego tomu książki sekuraka: Wprowadzenie do bezpieczeństwa IT. -15% z kodem: sekurak-book
Uważaj co wrzucasz do prywatnych repozytoriów na GitHubie – podatność opisana jako CFOR
Zespół trufflesecurity opisał bardzo ciekawy, ale bardzo nieintuicyjny i nieoczywisty na pierwszy rzut oka, design wykorzystywany przez GitHuba do zarządzania zależnościami między repozytoriami i forkami. Architektura tego rozwiązania pozwala, w pewnych okolicznościach użytkownikom na dostęp do commitów przesyłanych nie tylko do prywatnych repozytoriów ale także tych usuniętych. Nie jest to aż tak trywialne, żeby zaczynać panikę już teraz, ale definitywnie należy wziąć to pod uwagę w momencie publikowania kodu na GitHubie.
W raporcie nazwano tę “lukę” CFOR – Cross Fork Object Reference (w nawiązaniu do innej klasy podatności jaką jest IDOR, ponieważ pozwala na uzyskanie dostępu do zawartości commitów przez bezpośrednie odwołanie się do nich. Problem jest znany GitHubowi i na razie nie ma planów na zmianę.
Na co pozwala CFOR? Jest kilka scenariuszy, które przedstawili badacze.
Dostęp do danych z usuniętego forka
Jeśli niezsynchronizowany fork zostanie usunięty, to logiczna wydaje się sytuacja, w której nie można odtworzyć zmian wprowadzanych do nowego projektu. Okazuje się jednak, że jest to błędne założenie. W zaprezentowanym filmie występuje następująca sekwencja zdarzeń:
- tworzony jest fork publicznego repozytorium,
- dodawane są zmiany do sforkowanego projektu,
- fork jest usuwany.
Proces ten dobrze ukazuje grafika zamieszczona w oryginalnym artykule.
![](https://sekurak.pl/wp-content/uploads/2024/07/Zrzut-ekranu-2024-07-26-o-15.44.20-1000x535.png)
Mimo braku wykonania pull requestu, dane – mogłoby się wydawać – niepowiązane z oryginalnym projektem są wciąż dostępne, mimo że repozytorium, do którego trafiły już nie istnieje.
Dostęp do danych z usuniętego repozytorium
Sytuacja może też wystąpić w drugą stronę czyli w momencie gdy w czasie życia oryginalnego projektu, który został sforkowany. Jeśli właściciel pierwotnego repozytorium wprowadzi jakieś zmiany po forku, a następnie usunie pierwotny projekt, to dopóki istnieje jakiekolwiek repozytorium bazujące na nim, możliwe jest odwołanie się do zmian wprowadzanych po operacji forkowania.
Tak samo jak w poprzednim przypadku, można tę sekwencję zdarzeń przedstawić w postaci listy, dla łatwiejszego zrozumienia:
- oryginalny projekt na GitHubie jest rozwijany,
- powstaje jego fork,
- do pierwotnego repozytorium wprowadzane są zmiany,
- oryginalne repozytorium zostaje usunięte.
Taka sytuacja pozwala również, przy pomocy mechanizmu opisanego niżej, uzyskać dostęp do zmian, które teoretycznie zostały usunięte wraz z całym projektem.
![](https://sekurak.pl/wp-content/uploads/2024/07/Zrzut-ekranu-2024-07-26-o-15.45.04-1000x520.png)
Można spytać, dlaczego tak się dzieje. Odpowiedź przynosi dokumentacja, która wskazuje jak dokładnie przechowywane są informacje o repozytoriach i wprowadzanych zmianach.
![](https://sekurak.pl/wp-content/uploads/2024/07/Zrzut-ekranu-2024-07-26-o-15.45.38-1000x558.png)
Tutaj również skutki zaprezentowano przy pomocy krótkiego filmu:
Dostęp do zmian przeprowadzanych w prywatnych repozytoriach
Powyżej przedstawione zagadnienia, chociaż mogą nieść za sobą pewne konsekwencje bezpieczeństwa, w naszej opinii, nie są aż tak groźne jak przypadek, który przytoczymy w tym punkcie. Otóż zdarza się, że organizacje wprowadzając kontrybucje dla szeroko pojętej społeczności, publikują swoje projekty. Jednocześnie utrzymując prywatnego forka, który ma np. dodatkowe funkcje lub zawiera zahardkodowane klucze API, tokeny dostępowe etc (bardzo zła praktyka, polecamy mechanizmy bezpiecznego zarządzania sekretami lub chociaż zapoznanie się np. z tym artykułem).
Zakładając poniższą sekwencję zdarzeń:
- tworzony jest prywatny projekt, w którym wprowadzane są zmiany,
- tworzony jest prywatny fork, do którego dodawane są zmiany,
- oryginalny projekt jest publikowany.
Sytuację ukazuje grafika 4.
![](https://sekurak.pl/wp-content/uploads/2024/07/Zrzut-ekranu-2024-07-26-o-15.46.13-1000x570.png)
Od teraz wszystkie zmiany od utworzenia forka do publikacji repozytorium są dostępne dla każdego użytkownika przy pomocy zaprezentowanej metody. Czy to znaczy, że dane dodawane do prywatnego projektu po publikacji “okrojonej” wersji również będą dostępne? Okazuje się, że nie.
![](https://sekurak.pl/wp-content/uploads/2024/07/Zrzut-ekranu-2024-07-26-o-15.46.42-1000x449.png)
Demonstrację ataku również przedstawiono na filmiku:
Jak można uzyskać dostęp do commita? Potrzebny jest jego hash. Identyfikatory commitów w serwisie GitHub powstają z wykorzystaniem funkcji skrótu SHA-1. Bezpośrednie odwołanie do commita możliwe jest poprzez interfejs webowy z wykorzystaniem następującego URL:
https://github.com/<user/org>/<repo>/commit/<commit_hash>
Wydawać by się mogło, że wykorzystanie funkcji skrótu zwracającej 160 bitów to wystarczające zabezpieczenie, aby nie mówić o odgadnięciu tego identyfikatora. Jednak git pozwala na wykorzystanie skróconego identyfikatora.
Git is smart enough to figure out what commit you’re referring to if you provide the first few characters of the SHA-1 hash, as long as that partial hash is at least four characters long and unambiguous; that is, no other object in the object database can have a hash that begins with the same prefix.
To powoduje, że w najlepszym przypadku wystarczy odgadnięcie czterech znaków, a to jest już wartość, którą stosunkowo łatwo sprawdzić metodą pełnego przeglądu.
Adres tego commita:
https://github.com/trufflesecurity/trufflehog/commit/07f01e8337c1073d2c45bb12d688170fcd44c637
w skróconej formie, może wyglądać tak:
Jakby tego było mało, to GitHub publikuje API pozwalające na rejestrowanie publicznych zdarzeń. Oprócz tego, badacze słusznie zauważają, że istnieją serwisy, które agregują takie informacje. To powoduje, że odnalezienie potencjalnych celów jest jeszcze prostsze.
Trufflesecurity zgłosił problem w programie VDP, jednak firma przystaje na stanowisku, że jest to zamierzone działanie.
![](https://sekurak.pl/wp-content/uploads/2024/07/Zrzut-ekranu-2024-07-26-o-15.48.04-1000x130.png)
Mimo, że sposób przechowywania informacji przez GitHuba jest przejrzyście opisany w dokumentacji, to użytkownicy mogą traktować np. separację publicznych i prywatnych repozytoriów jako granicę bezpieczeństwa. Taka architektura łamie jedną z kluczowych zasad tworzenia interfejsów użytkownika – principle of least astonishment (ang. POLA).
Podsumowując, łatwo można dojść do konkluzji, że dopóki istnieje przynajmniej jeden fork repozytorium w danej sieci, tak długo można uzyskać dostęp do zmian przeprowadzanych w projekcie. To ważna uwaga, jak zostało słusznie zauważone, taki sposób działania powoduje, że jedyną skuteczną reakcją na przypadkowe wypchnięcie do sieci repozytoriów poufnych informacji takich jak klucze etc. jest ich zmiana (ang. rotation).
Dla użytkowników jest to niestety nauczka, że żeby bezpiecznie korzystać z danego rozwiązania, trzeba często, je bardzo dobrze zrozumieć. Dlatego zachęcamy do lektury oryginalnego postu oraz dokumentacji GitHuba wszystkich administratorów i deweloperów, którzy korzystają w swoich organizacjach (lub prywatnych projektach) z tego sposobu śledzenia zmian i przechowywania kodu.
~fc
Na Githubie to nie wiem, czy dałoby się inaczej. Możliwe, że w ten sposób mogą oszczędzić mnóstwo przesyrzeni dyskowej, tworząc tylko referencje do poszczególnych operacji commit. Jest przecież mnóstwo martwych forków, które nigdy nie będą modyfikowane.