Serwowanie stron z gita i bezpieczeństwo
Przeczytałem kiedyś na Niebezpieczniku artykuł o wycieku w sklepie influencerki Wersow. Artykuł zainspirował mnie przede wszystkim do zainstalowania wtyczki DotGit, ale do tej pory nie udało mi się znaleźc niczego spektakularnie ciekawego. Ot, proste strony statyczne czy kod, który i tak jest publiczny. Do dziś wątpiłem, że ktoś na serio wrzuciłby kredki do gita na prywatne repozytorium a potem rzucał git pull do synchronizacji w tym samym repozytorium.
Wyprzedzając pytania - administrator został powiadomiony i wpis został umieszczony już po naprawieniu problemu.
Od .git/config do haseł
Serfując po internecie z wyżej wymienioną wtyczką dostaniemy popup o znalezionym repozytorium .git, adresy zbierają się też w samym narzędziu więc można co jakiś czas spojrzeć co udało się przypadkowo zebrać. Spróbujmy wyciągnąć z tego coś sensownego.
![]() |
| Poręczna funkcjonalność |
Pobieramy repozytorium przez wtyczkę, wypakowujemy, przechodzimy do katalogu i możemy zobaczyć, że jest pusty. Po wpisaniu polecenia git status widać jednak jakie pliki są usunięte:
On branch master
Your branch is based on 'origin/master', but the upstream is gone.
(use "git branch --unset-upstream" to fixup)
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
deleted: .gitignore
deleted: .htaccess
deleted: .htpasswd
(...)
no changes added to commit (use "git add" and/or "git commit -a")Git służy do przechowywania historii zmian. Poprzednie commity są w formacie binarnym, w najprostszy sposób możemy dotrzeć do nich używając polecenia git restore .
$ ls -a
. .gitignore admin assets cron index.php mediacacheAdv modules static
.. .htaccess admin321 class css js mediacacheArticle resource templates
.git .htpasswd ajax.php config.php imagick.php mediaCache mediacachePhotorelation robots.txt tmpJak widać powyżej, pliki się odtworzyły. Pomijając hasła wpisane na sztywno w skryptach. Możemy nawet udać na potrzeby edukacyjne, że ich nie było. Najbardziej zaciekawił mnie plik .htpasswd[1]
Byłem ciekaw, czy uda mi się odgadnąć hasło do znalezionego użytkownika. Przykład jest zmyślony, ale ciąg zdarzeń analogiczny. Dla poniższego wpisu w .htpasswd:
admin:6YPqJe88Wz5fQNapisałem snippet w Pythonie i dopisałem kilka propozycji dla powyższego użytkownika, (chciałem chwilę później spróbować metodą słownikową) wyglądało to mniej więcej tak:
import crypt
passwords = ['admin', 'password', '123456', 'admin123']
hash = "6YPqJe88Wz5fQ"
for password in passwords:
if crypt.crypt(password, hash) == hash:
print(f"Password found: {password}")
break
else:
print("Password not found in common list")Po uruchomieniu dostałem potwierdzenie:
$ python3 htpasswd.py
Password found: admin123Co stało się dalej?
Po moim zgłoszeniu część rzeczy została ukryta w taki sposób:

Tu się będę już czepiał, ale chcę pokazać dlaczego jawna wersja oprogramowania w komunikacie błędu daje atakującemu nadmierną ilość informacji. Powyższa wersja Apache2 wskazuje prawdopodobnie na Ubuntu 22.04 LTS (jammy). Dlaczego? Bo ostatnia najnowsza wersja z Ubuntu 20.04 LTS (focal) to 2.4.41[2], natomiast w jammy już 2.4.52[3]. Najnowszy commit również wskazywałby, że strona nie jest juz jakiś czas aktualizowana

Wnioski
Ogromna prośba, żeby nie trzymać w gicie jawnie haseł. To nie jest odpowiednie miejsce. Jak widać, nawet w przypadku korzystania z prywatnego repozytorium coś po drodze może pójść nie tak i hasła mogą wyciec.
https://pl.wikipedia.org/wiki/.htpasswd Dostęp 19.02.2026 ↩︎
https://launchpad.net/ubuntu/focal/+source/apache2 Dostęp 19.02.2026 ↩︎
https://packages.ubuntu.com/jammy/apache2 Dostęp 19.02.2026 ↩︎
