ARK. B12Parametr monitoringuBezpieczeństwo · lista 50 parametrów

Ekspozycja .git/HEAD

ważność wysokamierzonysposób exposure

Czy repozytorium Git jest publicznie dostępne. Ujawnia kod, klucze i historię commitów.

ARK. 1

WIKI

artykuł z 16.09.2026 · źródeł 10

Ekspozycja .git/HEAD to parametr monitoringu stron internetowych, który sprawdza, czy pod adresem /.git/HEAD serwer WWW oddaje plik z katalogu repozytorium Git, zamiast odmówić dostępu albo zgłosić jego brak. Dostępny HEAD jest sygnałem, że cały katalog .git, a z nim historia projektu, może być do pobrania. Pomiar kończy się jednym z trzech wyników: plik dostępny publicznie, plik niedostępny albo nie udało się uzyskać odpowiedzi. W zwykłym repozytorium Git katalog .git leży w katalogu głównym drzewa roboczego [1].

Jak działa

Katalog .git ma stały układ. HEAD wskazuje aktywną gałąź w przestrzeni refs/heads/ albo, w stanie odłączonym, zapisuje wprost konkretny commit [1]. Pliki refs/heads/<nazwa> przechowują ostatni commit każdej gałęzi, a packed-refs zawiera te same informacje w zwartej postaci [1]. Plik config to konfiguracja repozytorium, logs zapisuje zmiany referencji, a index to bieżący indeks [1].

Treść projektu leży w objects. Git jest magazynem adresowanym treścią: każdy obiekt ma sumę SHA-1, a zapisany jest skompresowany zlib w podkatalogu nazwanym dwoma pierwszymi znakami sumy i w pliku nazwanym pozostałymi 38 znakami [2]. Commit wskazuje drzewo katalogów projektu i commit poprzedni, więc od jednego commita da się przejść całą historię [2]. Wiele obiektów może też leżeć w paczkach w objects/pack [1].

Znajomość układu wystarcza do odtworzenia repozytorium bez spisu katalogu. Adres każdego obiektu wynika z jego sumy [2], a plik index zaczyna się sygnaturą DIRC i dla każdego śledzonego pliku zawiera sumę obiektu oraz ścieżkę względem katalogu głównego projektu [3].

RYS. 1.1Odtwarzanie repozytorium po HTTP

Narzędzie git-dumper opisuje ten mechanizm wprost. Gdy serwer pokazuje spis katalogu, pobiera .git rekurencyjnie [4]. W przeciwnym razie pobiera typowe pliki (.git/HEAD, .git/index i inne), szuka referencji w HEAD, logs/HEAD, config i packed-refs, zbiera sumy obiektów z packed-refs, index, refs i logs, pobiera obiekty rekurencyjnie po rodzicach commitów, a na końcu odtwarza drzewo robocze poleceniem git checkout . [4].

Standardy i specyfikacje

  • gitrepository-layout opisuje pliki i katalogi repozytorium, w tym HEAD, config, refs, packed-refs, logs, index i objects [1].
  • Format indeksu Git definiuje nagłówek z sygnaturą DIRC, numerem wersji i liczbą wpisów oraz wpisy z sumą obiektu i ścieżką pliku [3].
  • CWE-527 („Exposure of Version-Control Repository to an Unauthorized Control Sphere”) to repozytorium CVS, Git lub innego systemu kontroli wersji zapisane w katalogu, archiwum albo zasobie dostępnym dla nieuprawnionych [6]. Jest potomkiem CWE-552 [6]. MITRE wymienia skutki: nazwy użytkowników, nazwy plików, ścieżki, adresy IP i szczegółowe różnice zmian, które mogą ujawnić fragmenty kodu nigdy nieprzeznaczone do publikacji [6].

Zagrożenia i skutki

Skala. W lipcu 2015 roku zespół Internetwache przeskanował listę miliona popularnych domen Alexa i znalazł około 9700 publicznie dostępnych repozytoriów Git [5]. Opisał odtwarzanie repozytorium bez spisu katalogu przez pobieranie obiektów wskazanych w plikach takich jak refs/heads/master i analizę kolejnych commitów i drzew [5].

Sekrety w konfiguracji i historii. Ten sam raport zauważa, że ponad 100 projektów zapisało w .git/config adres repozytorium razem z nazwą użytkownika i hasłem do uwierzytelniania HTTP [5]. Takie dane dawały dostęp do kont w usługach hostujących repozytoria, a w części repozytoriów zespół znalazł dane dostępowe do AWS, baz danych, SMTP i FTP [5]. Plik usunięty z bieżącej wersji projektu nadal istnieje w starszych commitach, bo każdy commit wskazuje własne drzewo [2].

RYS. 1.2Od publicznego .git do sekretów

Usunięcie z historii nie wystarcza. GitHub zaleca, by przy wycieku hasła, tokenu lub klucza najpierw go unieważnić albo wymienić, a dopiero potem rozważać przepisywanie historii [7]. Usunięcie danych z historii wymaga koordynacji ze wszystkimi, którzy mają kopię repozytorium [7].

Blokada w serwerze. Domyślna konfiguracja Apache odmawia dostępu tylko do plików pasujących do .ht* [10], więc katalog .git nie jest nią objęty. Dyrektywa DirectoryMatch stosuje zestaw reguł do katalogów, których ścieżka pasuje do wyrażenia regularnego [9]; Internetwache proponuje na niej regułę Require all denied dla ścieżek zawierających /.git/ albo trzymanie repozytorium poza katalogiem dokumentów [5]. Przykładowa konfiguracja nginx dla WordPressa zawiera blok location ~ /\. z deny all, opisany jako blokada plików ukrytych [8].

Przykłady

SytuacjaOdpowiedź na GET /.git/HEADZnaczenie
Repozytorium w katalogu dokumentów, bez reguł odmowy [1] [10]200 z referencją gałęzi lub sumą commitahistoria do odtworzenia [4]
Jak wyżej, ze spisem katalogu [4]200, a /.git/ pokazuje listę plikówpobranie rekurencyjne [4]
Spis katalogu wyłączony [3] [4]200odtworzenie przez index i sumy obiektów
Apache z regułą DirectoryMatch dla .git [5] [9]odmowa dostępurepozytorium istnieje, nie jest podawane
nginx z blokiem location ~ /\. [8]odmowa dostępublokada obejmuje wszystkie pliki ukryte
Repozytorium poza katalogiem dokumentów [5]brak plikunic do pobrania
Hasło w .git/config lub w starym commicie [5]200sekret do unieważnienia [7]
TAB. 1.1Przypisy10
  1. [1] gitrepository-layout — Git Repository Layout · Git Project
  2. [2] Pro Git, 10.2 Git Internals — Git Objects · Git Project / Scott Chacon, Ben Straub
  3. [3] Git index format · Git Project
  4. [4] git-dumper — README · arthaud/git-dumper
  5. [5] Don't publicly expose .git or how we downloaded your website's sourcecode — An analysis of Alexa's 1M · Internetwache.org
  6. [6] CWE-527: Exposure of Version-Control Repository to an Unauthorized Control Sphere · MITRE
  7. [7] Removing sensitive data from a repository · GitHub Docs
  8. [8] Nginx — Advanced Administration Handbook · WordPress.org
  9. [9] Apache Core Features — dyrektywa DirectoryMatch · Apache Software Foundation
  10. [10] httpd.conf.in — domyślna konfiguracja Apache HTTP Server · Apache Software Foundation
ARK. 2

STATS

wyniki z systemu · tylko liczby zbiorcze
TAB. 2.1Odczyty per strona

Ten parametr nie zapisuje odczytu per strona — przebieg zostawia tylko ustalenia, więc liczby sprawdzonych stron i wyników „ok” system nie ma. Pojawią się po wdrożeniu zapisu przebiegów per strona per parametr.

TAB. 2.3Ustalenia

Ten parametr nie otworzył jeszcze żadnego ustalenia w bazie LAB247. Pusto nie znaczy „czysto” — znaczy, że nic nie przekroczyło reguły.

TAB. 2.4Przebiegi z tym sposobem sprawdzeniaod 09.09.2026
Przebiegów
33sposób exposure
W 30 dni
33przebiegów
Ostatni
19.09.2026start przebiegu
Stron w przebiegach
33 przebiegów bez liczby stron
ARK. 3

CARD

karta z kodu CREATO_PING, odczyt 16.09.2026
RYS. 3.1Droga parametru przez system: Ekspozycja .git/HEAD
TAB. 3.1Pomiarpliki: 6
Obszar i ważnośćBezpieczeństwo · wysoka (B12)
Workflow i częstotliwośćcreato_ping_security_v2 · P3 działa na LAB247cron co 24 h, T1–T3; T4 raz po anomalii · Dokładny skan. dns_integrity porównuje NS, MX, SPF i DMARC z wzorcem z poprzedniego przebiegu.
Sonda i helpersposób exposure · CREATO_PING/helpers/exposure_check.py
Testy
  1. Tylko przebieg P3; przed sondami strażnik losowej ścieżki (200 z treścią = sondy pominięte).
  2. GET https://domena/.git/HEAD bez podążania za przekierowaniami; treść strumieniem do 64 KB, oceniane pierwsze 5000 znaków.
  3. Reguła: kod 200 i niepusta treść — ani referencja gałęzi, ani suma commita nie są sprawdzane.
  4. Inne pliki repozytorium (config, index, obiekty) nie są pobierane; sprawdzany jest tylko .git w katalogu głównym.
Typ wyniku0 albo 1 ustalenie exposure_git
Jednostkabrak — wynik jakościowy; w dowodzie ścieżka, kod HTTP i długość treści
Próg i regułaTimeout odpowiedzi 15 s, połączenia 5 s. Reguła: kod 200 + niepusta treść = exposure_git.
Gdzie leżą pokrętłaCREATO_PING/helpers/exposure_check.py → PROBES (/.git/HEAD, reguła 200+nonempty), _soft_200CREATO_PING/helpers/config.py → TIMEOUTS["exposure"], TIMEOUTS["security_connect"]CREATO_PING/helpers/security_runner.py → _TASK_SEVERITIESCREATO_PING/config/incident_policy.toml → [finding] exposure_git
Retencja odczytówOdczytu per strona nie zapisujemy — zostaje tylko ustalenie w tabeli findings (otwarcie, zamknięcie, dowód). Replay po surowych odczytach dziś niemożliwy.
Znane rozbieżności
  1. Reguła nie sprawdza, czy to naprawdę plik HEAD: kod 200 ze stroną HTML daje ustalenie pilne, a format jednej linii z referencją nie jest weryfikowany.
  2. Ustalenie nie potwierdza, że repozytorium da się pobrać — config, index i obiekty nie są sprawdzane.
  3. Repozytoria motywów i wtyczek wdrażanych przez git w podkatalogach wp-content nie są sondowane.
  4. alert=true w polityce nie jest czytane ani przez kod, ani przez n8n — PODATNA nie wysyła powiadomienia.
  5. Brak trzeciego stanu, brak śledzenia przekierowań i brak sygnału zamknięcia — wspólne dla sond ekspozycji.
kandydaci do pętli: kod a opis parametru albo specyfikacja
Karta przepisana zCREATO_PING/helpers/exposure_check.py · CREATO_PING/helpers/config.py · CREATO_PING/config/incident_policy.toml · CREATO_PING/helpers/security_runner.py · CREATO_PING/helpers/clickup_writer_v2.py · CREATO_PING/workflows/_prod/creato_ping_security_v2.json · odczyt 16.09.2026
TAB. 3.2Co oznacza failtypów ustaleń: 1

Powaga pilna w helperze i w polityce, pewność ewidentna, skutek PODATNA — subtask z priorytetem pilnym, status strony przeliczony na PODATNA. Kolejne przebiegi odświeżają opis i datę; helper nie wysyła sygnału zamknięcia.

UstaleniePowagaPewnośćSkutekSubtask / alarmCo zrobić
Publiczne repozytorium .gitexposure_gitPilneEwidentnePODATNAtak / takZablokuj dostęp do katalogu .git na serwerze.
ARK. 4

LOOP

pętli: 2
RYS. 4.1Pętla parametru — sześć etapów
TAB. 4.1Trafność, 30 dnialarmy · prawdziwe · fałszywe · bez rozstrzygnięcia

Trafności jeszcze nie liczymy: zamknięcie subtaska nie niesie dziś werdyktu (prawdziwy / fałszywy / nie dało się sprawdzić). Cztery liczby pojawią się, gdy każde zamknięcie dostanie werdykt — to warunek startu pętli 1.

TAB. 4.2Pętle2 · zmian: 3 · wpływających na cały system: 3
Strażnik losowej ścieżki i dłuższy limit czasu dla sond ekspozycjizamknięta historyczna 2026-09-05

Sygnał: Tarcze antybotowe hostingu, strony parkingowe i serwery catch-all odpowiadają 200 na każdą ścieżkę, więc sondy oparte na kodzie 200 dawały „wystawiony” wszędzie. Równocześnie sondy na wolnych hostingach odpowiadały po około 15 s, a limit 5 s ucinał je bez śladu. · dotyczy też: Ekspozycja .env, Ekspozycja plików wrażliwych, Ekspozycja .htaccess.bak, Dostępność xmlrpc.php, REST API: enumeracja użytkowników, Dostępność readme.html, Dostępność wp-cron.php, Ekspozycja kopii zapasowych, Ekspozycja zrzutu bazy, Ekspozycja manifestów dev, Ekspozycja .DS_Store

  1. 1. Zbiórkaręcznieodczyt z nocnego skanu, bez zapisu per strona
  2. 2. Werdyktręcznieprzegląd skanera: 200 na wszystko i ciche timeouty to fałszywe wyniki
  3. 3. Miarabrakliczników trafności wtedy nie było
  4. 4. Kartabrakkarta parametru powstała 2026-09-16
  5. 5. Zmianazrobionestrażnik ścieżki, 15 s, logowanie błędów
  6. 6. Replaybrakbrak zapisanych odczytów do replayu
DataZmianaPowódWpływ na systemCommit · replay
2026-09-05Przed sondami GET losowej, nieistniejącej ścieżki; odpowiedź 200 z treścią = zero sond i jedno ustalenie exposure_scan_unreliable (niska powaga, bez subtaska).helpers/exposure_check.py · config/incident_policy.tomlOdpowiedź 200 na losową ścieżkę dowodzi, że kod 200 na tym serwerze nic nie znaczy; dalsze sondowanie tarczy grozi banem IP monitoringu.cały system Obejmuje wszystkie sondy ekspozycji naraz i wprowadza typ „nie dało się sprawdzić”; tę samą konwencję dostało wykrywanie wtyczek. Ustalenie ma niską powagę, więc filtr przebiegu je odrzuca i w produkcji nie zostawia śladu.b0fc77cbez replayubez zapisu zatwierdzenia
2026-09-05Limit odpowiedzi z 5 s na 15 s i połączenia z 2 s na 5 s, przeniesione do config.py; błąd sieci sondy logowany zamiast cichego pustego wyniku; do 4 sond naraz na stronę.helpers/config.py · helpers/exposure_check.py · helpers/html_fetch.py · helpers/wp_fingerprint.pyWolne hostingi odpowiadały po około 15 s, a pusty wynik po timeoucie był nieodróżnialny od „sprawdzone, czysto”.cały system Limit połączenia 5 s przejęło wspólne pobieranie HTML całego skanu bezpieczeństwa i wykrywanie wersji — strony z wolnym TLS przestały wypadać z całego skanu.b0fc77cbez replayubez zapisu zatwierdzenia
Limit 64 KB czytanej odpowiedzi po awarii pamięcizamknięta historyczna 2026-07-19

Sygnał: Brak pamięci podczas skanu: publiczny debug.log jednej ze stron był bardzo duży, a klient HTTP buforował całą odpowiedź. · dotyczy też: Sitemap.xml, Ekspozycja plików wrażliwych, Ekspozycja .env, Ekspozycja .htaccess.bak, Dostępność xmlrpc.php, REST API: enumeracja użytkowników, Dostępność readme.html, Dostępność wp-cron.php, Ekspozycja kopii zapasowych, Ekspozycja zrzutu bazy, Ekspozycja manifestów dev, Ekspozycja .DS_Store

  1. 1. Zbiórkaręcznieodczyt z nocnego skanu, bez zapisu per strona
  2. 2. Werdyktręcznieawaria procesu przypisana ścieżce debug.log
  3. 3. Miarabrakliczników trafności wtedy nie było
  4. 4. Kartabrakkarta parametru powstała 2026-09-16
  5. 5. Zmianazrobionestrumień z limitem 64 KB
  6. 6. Replaybrakbrak zapisanych odczytów do replayu
DataZmianaPowódWpływ na systemCommit · replay
2026-07-19Odpowiedź sondy czytana strumieniem do 64 KB; do oceny idzie pierwsze 5000 znaków.helpers/exposure_check.py · helpers/html_fetch.py · helpers/sitemap_check.pyDo rozpoznania ekspozycji wystarcza początek pliku; zmiana dotyczy sposobu czytania, nie werdyktu.cały system Brak pamięci w helperze zatrzymywał cały proces skanu bezpieczeństwa partii stron; ten sam limit dostało sprawdzenie sitemap.343b699bez replayubez zapisu zatwierdzenia
Blog 24/7
20.09Zastrzeżony PESEL: zmiana raz na 30 minut, blokada przy wypłaciedobreprogramy.pl20.09Fałszywe SMS-y od GITD o mandacie za autostradę wyłudzają dane kartyinstalki.pl20.09Pakiet npm indexed-btree omija blokadę skryptów instalacyjnychbleepingcomputer.com19.09SolarWinds łata CVE-2026-28326 w Access Rights Manager, zdalny kod bez logowaniathehackernews.com19.09Orkes Conductor: luka CVE-2026-58138 atakowana w sieci, poprawka w wersji 3.30.2thehackernews.com19.09Trzy luki jądra Linux w katalogu CISA KEV, Red Hat potwierdza aktywne atakithehackernews.com18.09Publiczne exploity na cztery luki jądra Linux dają lokalnie uprawnienia rootthehackernews.com18.09Brevo: skradziony klucz API Cloudflare i skrypty ClickFix na stronach klientówbleepingcomputer.com18.09WaterPlum z Korei Północnej zainfekowała 30 000 urządzeń w 100 krajachtherecord.media18.09Jedna zgoda OAuth daje napastnikowi dostęp do poczty i plików mimo MFAdarkreading.com