Ekspozycja manifestów dev
ważność niskamierzonysposób exposure
Pliki composer.json i package.json dostępne publicznie. Nie są wyciekiem danych, ale wydają atakującemu listę bibliotek i wersji.
WIKI
artykuł z 16.09.2026 · źródeł 7Ekspozycja manifestów dev to parametr monitoringu stron internetowych, który sprawdza, czy w katalogu głównym witryny serwer oddaje pliki composer.json albo package.json, czyli manifesty zależności projektu PHP i JavaScript. Pomiar kończy się jednym z trzech wyników: manifest dostępny, manifest niedostępny albo nie udało się uzyskać odpowiedzi. Plik composer.json opisuje pakiet i jego zależności według schematu Composera [1], a package.json pełni tę rolę w ekosystemie npm [3].
Jak działa
W composer.json pole name składa się z nazwy dostawcy i nazwy projektu rozdzielonych ukośnikiem, np. monolog/monolog [1]. Pole require to mapa pakietów wymaganych przez projekt, a require-dev wymienia pakiety potrzebne do rozwoju i testów [1]. W package.json zależności to obiekt, który przypisuje nazwie pakietu zakres wersji, np. ^version albo 1.2.x [3]. Pola name i version są wymagane przy publikacji pakietu, a w projekcie, który nie będzie publikowany, są opcjonalne [3].
Manifest podaje zakresy, plik blokady podaje dokładne wersje. Composer rozwiązuje zależności z composer.json i zapisuje wszystkie pakiety z dokładnymi wersjami do composer.lock [2]; dokumentacja zaleca dodanie tego pliku do repozytorium [2]. package-lock.json opisuje dokładne drzewo zainstalowanych pakietów, a przy każdym z nich podaje wersję i miejsce, z którego go pobrano [4].
Standardy i specyfikacje
- Schemat composer.json definiuje pola manifestu Composera;
namejest wymagane dla publikowanych bibliotek [1]. - Dokumentacja package.json opisuje zależności, zależności deweloperskie i pole
private: przy ustawieniu"private": truenpm odmówi publikacji pakietu [3]. - npm audit wysyła do rejestru opis zależności projektu i prosi o raport znanych podatności. Domyślnie wymaga pliku
package-lock.json, a każde ostrzeżenie zawiera m.in. nazwę, powagę i polevulnerable_versions[5]. - CWE-200 („Exposure of Sensitive Information to an Unauthorized Actor”) wymienia wśród informacji wrażliwych stan i środowisko systemu, np. system operacyjny i zainstalowane pakiety [6]. MITRE oznacza ten wpis jako niezalecany do przypisywania konkretnym podatnościom, bo opisuje skutek, a nie przyczynę [6].
Zagrożenia i skutki
Dopasowanie do znanych podatności. Nazwa pakietu i jego wersja to dane, które npm audit wysyła do rejestru, żeby dostać ostrzeżenia z zakresem podatnych wersji [5]. Kto odczyta manifest albo plik blokady z cudzego serwera, wykona to samo porównanie bez dostępu do kodu. Zakres z manifestu wskazuje wersję mniej dokładnie niż wpis w pliku blokady [3] [4], więc dostępny composer.lock albo package-lock.json zdradza więcej niż sam manifest.
Mapa wtyczek i motywów. W projektach, które zarządzają WordPressem przez Composera, manifest wymienia rdzeń, wtyczki i motywy jako zależności. Szablon Bedrock instaluje w ten sposób np. pakiety roots/wordpress i wp-plugin/woocommerce [7]. Jednocześnie Bedrock wskazuje jako publiczny katalog główny podkatalog web, więc manifesty zostają poza drzewem serwera [7].
Skutek pośredni. Manifest nie daje dostępu do strony. Skraca rekonesans: zamiast zgadywać komponenty, napastnik dostaje ich listę.
Przykłady
| Sytuacja | Plik pod adresem | Co ujawnia |
|---|---|---|
Bedrock z katalogiem publicznym web [7] | brak | nic, manifesty poza drzewem serwera |
| Projekt Composera wdrożony w całości do katalogu WWW | composer.json | nazwy pakietów i zakresy wersji [1] |
| Jak wyżej, z plikiem blokady [2] | composer.lock | dokładne wersje wszystkich pakietów |
Motyw budowany przez npm, package.json bez pola name [3] | package.json | zakresy wersji narzędzi i bibliotek |
package-lock.json w katalogu WWW [4] | package-lock.json | wersja i źródło każdego pakietu w drzewie |
- [1] The composer.json schema · Composer
- [2] Basic usage — composer.lock · Composer
- [3] package.json · npm Docs
- [4] package-lock.json · npm Docs
- [5] npm audit · npm Docs
- [6] CWE-200: Exposure of Sensitive Information to an Unauthorized Actor · MITRE
- [7] Bedrock — WordPress boilerplate · Roots
STATS
wyniki z systemu · tylko liczby zbiorczeTen 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.
Ten parametr nie otworzył jeszcze żadnego ustalenia w bazie LAB247. Pusto nie znaczy „czysto” — znaczy, że nic nie przekroczyło reguły.
- Przebiegów
- 33sposób exposure
- W 30 dni
- 33przebiegów
- Ostatni
- 19.09.2026start przebiegu
- Stron w przebiegach
- —33 przebiegów bez liczby stron
CARD
karta z kodu CREATO_PING, odczyt 16.09.2026| Obszar i ważność | Bezpieczeństwo · niska (B29) |
|---|---|
| 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 helper | sposób exposure · CREATO_PING/helpers/exposure_check.py |
| Testy |
|
| Typ wyniku | 0 albo 1 ustalenie exposure_dev_manifest (dwie ścieżki sklejone w jedno, powaga niska) — dziś odrzucane przed zapisem |
| Jednostka | brak — wynik jakościowy |
| Próg i reguła | Timeout odpowiedzi 15 s, połączenia 5 s. Reguła: kod 200 + poprawny obiekt JSON w pierwszych 5000 znakach + klucz require albo name. |
| Gdzie leżą pokrętła | CREATO_PING/helpers/exposure_check.py → PROBES (json_manifest:require, json_manifest:name)CREATO_PING/helpers/config.py → TIMEOUTS["exposure"], TIMEOUTS["security_connect"]CREATO_PING/helpers/security_runner.py → _TASK_SEVERITIESCREATO_PING/config/incident_policy.toml → [finding] exposure_dev_manifest |
| Retencja odczytów | Nic: helper nadaje powagę poniżej wysokiej, filtr przebiegu odrzuca ustalenie przed zapisem, a produkcja idzie z --no-stats. Nie ma ani odczytu per strona, ani ustalenia, ani licznika — statystyki i replay niemożliwe. |
| Znane rozbieżności |
|
| Karta przepisana z | CREATO_PING/helpers/exposure_check.py · CREATO_PING/helpers/security_runner.py · CREATO_PING/config/incident_policy.toml · CREATO_PING/workflows/_prod/creato_ping_security_v2.json · odczyt 16.09.2026 |
Brak skutku w produkcji: helper nadaje powagę niską, a filtr przebiegu przepuszcza do zapisu tylko pilną i wysoką, więc ustalenie odpada, zanim przeczyta je polityka incydentów. Przebieg idzie z --no-stats, więc nie zostaje nawet licznik. Nie powstaje subtask, zmiana statusu strony ani ustalenie w bazie.
| Ustalenie | Powaga | Pewność | Skutek | Subtask / alarm | Co zrobić |
|---|---|---|---|---|---|
| Publiczny manifest zależnościexposure_dev_manifest | Niskie | Ewidentne | bez wpływu | nie / nie | Zablokuj dostęp do plików manifestów na serwerze. |
LOOP
pętli: 2Trafnoś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.
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, Ekspozycja .git/HEAD, Dostępność readme.html, Dostępność wp-cron.php, Ekspozycja kopii zapasowych, Ekspozycja zrzutu bazy, Ekspozycja .DS_Store
- 1. Zbiórkaręcznieodczyt z nocnego skanu, bez zapisu per strona
- 2. Werdyktręcznieprzegląd skanera: 200 na wszystko i ciche timeouty to fałszywe wyniki
- 3. Miarabrakliczników trafności wtedy nie było
- 4. Kartabrakkarta parametru powstała 2026-09-16
- 5. Zmianazrobionestrażnik ścieżki, 15 s, logowanie błędów
- 6. Replaybrakbrak zapisanych odczytów do replayu
| Data | Zmiana | Powód | Wpływ na system | Commit · replay |
|---|---|---|---|---|
| 2026-09-05 | Przed 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.toml | Odpowiedź 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-05 | Limit 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.py | Wolne 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 |
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, Ekspozycja .git/HEAD, Dostępność readme.html, Dostępność wp-cron.php, Ekspozycja kopii zapasowych, Ekspozycja zrzutu bazy, Ekspozycja .DS_Store
- 1. Zbiórkaręcznieodczyt z nocnego skanu, bez zapisu per strona
- 2. Werdyktręcznieawaria procesu przypisana ścieżce debug.log
- 3. Miarabrakliczników trafności wtedy nie było
- 4. Kartabrakkarta parametru powstała 2026-09-16
- 5. Zmianazrobionestrumień z limitem 64 KB
- 6. Replaybrakbrak zapisanych odczytów do replayu
| Data | Zmiana | Powód | Wpływ na system | Commit · replay |
|---|---|---|---|---|
| 2026-07-19 | Odpowiedź sondy czytana strumieniem do 64 KB; do oceny idzie pierwsze 5000 znaków.helpers/exposure_check.py · helpers/html_fetch.py · helpers/sitemap_check.py | Do 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 |