4digital Lab4digital Lab4digital Lab4digital Lab
← Wszystkie badania

Lab · Studium przypadku

Wyłącznik awaryjny, którego nikt nie podłączył

W skrócie: Odtworzyłem historię wyłącznika awaryjnego, który miał kod, testy i dokumentację, lecz nie uczestniczył w wykonywaniu zleceń. Jego archiwizacja nie wymagała zmian w kodzie wykonawczym, a poprawiona implementacja również nie znalazła się na jednej z rzeczywistych tras zleceń. Przypadek pokazuje różnicę między istnieniem zabezpieczenia a skutecznością jego integracji.

  • bezpieczenstwo
  • systemy-handlowe
  • weryfikacja
  • fail-open
Pochodzenie materiału

Artykuł opracowany z pomocą AI na podstawie historycznej rekonstrukcji kodu, dokumentacji i historii zmian oraz późniejszej relacji autora o przerwie w pracach. Materiały źródłowe pozostają niepubliczne.

Wersja
1.0

01 / Wyłącznik, którego usunięcia system nie zauważył

Z prywatnego, eksperymentalnego systemu handlowego zarchiwizowano całą bibliotekę wyłącznika awaryjnego. Nie wymagało to zmiany kodu wykonawczego ani przebudowy fabryk tworzących usługi.

Powód był prosty: na ścieżce wysyłania zleceń nikt tego zabezpieczenia nie wywoływał.

Wcześniej wyłącznik otrzymał własną bibliotekę, testy, narzędzie konsolowe, sześć reguł alertów, dwa pulpity oraz 707-wierszowy podręcznik operacyjny. Dokumentacja opisywała pięć warstw ochrony, deklarowała skuteczną integrację i kończyła się statusem PRODUCTION READY.

W tym samym commicie istniał jednak kod przeczący tej deklaracji.

System nie miał użytkowników ani wdrożeń produkcyjnych. Był prywatnym eksperymentem, a nie środowiskiem obsługującym rzeczywiste środki klientów. Historia dotyczy defektu integracji, nie potwierdzonego incydentu produkcyjnego.

02 / Pięć warstw ochrony i brak jednego połączenia

Mechanizm był widoczny w kodzie.

Fabryka tworząca usługę zleceń nie przekazywała jej wyłącznika awaryjnego. Sama usługa dopuszczała jego brak: parametr był opcjonalny, a funkcja sprawdzająca kończyła działanie natychmiast, jeśli zabezpieczenia nie dostarczono.

Nie powodowało to błędu. Operacja mogła być kontynuowana bez kontroli.

Dodatkowo implementacja przewidywała zachowanie fail-open: w niektórych sytuacjach błędu sprawdzenia dopuszczała dalsze działanie w imię dostępności. Dokumentacja opisywała to jako zamierzoną właściwość.

Przy niepodłączonym wyłączniku te dodatkowe ścieżki błędów nie były jednak potrzebne do obejścia zabezpieczenia. Funkcja wracała wcześniej.

Zabezpieczenie mogło więc działać poprawnie w izolowanym teście, w którym ktoś jawnie przekazywał jego instancję. Nie oznaczało to, że usługa używała go podczas wykonywania zleceń.

Co więcej, deklarowane pięć warstw ochrony nie przekładało się na pięć skutecznie podłączonych punktów kontroli. Komponent bramy API istniał, ale nie został zarejestrowany w aplikacji. Inne sprawdzenia znajdowały się w klasach, których nie konstruowano na wykonywanych ścieżkach.

Testowany komponent i komponent uczestniczący w wykonaniu to dwie różne rzeczy.

03 / Zielony status bez działającej ochrony

Brak integracji nie musiał objawiać się awarią.

W kodzie znajdowała się kontrola zdrowia, która przy braku podłączonego wyłącznika zwracała status OK i informację, że handel jest dozwolony.

Nie ma dowodu, że ten punkt końcowy rzeczywiście obsługiwał zapytania w działającym środowisku. Samo zachowanie zapisanej gałęzi kodu jest jednak istotne: brak zabezpieczenia traktowano jako stan poprawny.

Podobny kontrast występował w monitoringu.

W zachowanym zrzucie bazy jednej instancji znajdowały się oba pulpity wyłącznika. W tabelach reguł alertowych nie było natomiast żadnej reguły. Pliki i dokumentacja alertów istniały, lecz nie dowodziło to ich aktywacji w tej instancji.

Dodatkowo obok dokumentu ogłaszającego zakończenie integracji istniało zgłoszenie o priorytecie P0, opisujące brak podłączenia wyłącznika do usług handlowych.

Zawierało osiemnaście kryteriów odbioru. Do czasu usunięcia dokumentu żadne nie zostało odhaczone.

Nie był to zatem problem, którego nigdzie nie zapisano. Deklaracja zakończenia prac i opis brakującej integracji znajdowały się w tym samym repozytorium.

Zachowane źródła nie rozstrzygają, kto znał treść obu dokumentów ani dlaczego zadanie pozostało otwarte.

04 / Co wydarzyło się po wznowieniu prac

Między deklaracją skutecznej integracji a archiwizacją biblioteki upłynęły 222 dni.

Ten odstęp wymaga jednak kontekstu. W badanym repozytorium wystąpiła przerwa wynosząca 168 dni i niemal 19 godzin bez commitów. Rozwój projektu został w tym okresie świadomie wstrzymany.

Nie oznacza to, że brak commitów dowodzi braku wszelkiej aktywności. Nie można jednak utożsamiać całych 222 dni z okresem nieprzerwanej pracy nad systemem i ignorowania defektu.

Po wznowieniu zmian udokumentowano problem starego mechanizmu, a dla nowej implementacji przyjęto zasadę fail-closed: gdy bezpieczeństwa operacji nie można potwierdzić, należy jej zabronić.

Następnie starą bibliotekę zarchiwizowano.

Komunikat tej zmiany wskazywał, że pozostałe importy wyłącznika były wykorzystywane wyłącznie do sprawdzania typów, czyli nie wykonywały się podczas działania programu.

Archiwizacja nie wymagała zmian w fabrykach ani ingerencji w wykonywaną logikę.

Było to jedno z najmocniejszych potwierdzeń problemu: zabezpieczenie można było wyjąć, ponieważ żadna z pozostałych aktywnych zależności go nie potrzebowała.

05 / Poprawiony wyłącznik, inna ścieżka

System-następca usuwał istotne wady wcześniejszego rozwiązania.

Zależność od wyłącznika stała się wymagana w nowym komponencie, a błędy sprawdzenia miały prowadzić do odmowy operacji zamiast jej przepuszczenia.

Nie oznaczało to jednak, że poprawiony mechanizm obejmował każdą trasę wykonania.

W zachowanym zapisie udokumentowano zlecenie demonstracyjne wykonane przez nową ścieżkę. Analiza kodu tej trasy nie wykazała wywołania wyłącznika. Ten sam brak występował w późniejszej rewizji.

Trasa miała natomiast inne, rzeczywiste zabezpieczenie: była konstrukcyjnie ograniczona do trybu demonstracyjnego i odrzucała próbę wysłania zlecenia z użyciem prawdziwego kapitału.

To rozróżnienie ma znaczenie. Nie wykazano niekontrolowanego handlu rzeczywistymi środkami.

Wykazano natomiast, że poprawiony mechanizm bezpieczeństwa nadal nie obejmował jednej z tras, na których rzeczywiście wykonywano operacje.

Nie wiadomo, czy była to świadoma konsekwencja ograniczenia trasy do trybu demonstracyjnego, czy pozostawiona rozbieżność integracyjna.

Sam fakt poprawienia implementacji nie rozstrzyga tego pytania.

06 / Co właściwie zostało sprawdzone

Przypadek pokazuje trzy różne poziomy kontroli.

Pierwszy dotyczy istnienia mechanizmu. Można sprawdzić jego kod, testy, dokumentację i interfejs.

Drugi dotyczy zachowania mechanizmu po wywołaniu. Można sprawdzić, czy w określonych warunkach blokuje operację, prawidłowo zapisuje stan i reaguje na błędy.

Trzeci dotyczy integracji: czy rzeczywista ścieżka wykonania w ogóle wywołuje ten mechanizm.

W analizowanym przypadku najważniejszy problem znajdował się na trzecim poziomie. Poprawność dwóch pierwszych nie mogła go rozwiązać.

Kontrola bezpieczeństwa powinna więc obejmować nie tylko sam komponent, lecz także drogę od wejścia systemu do operacji, którą ma on chronić.

Istnienie zabezpieczenia nie jest dowodem, że zabezpieczenie uczestniczy w działaniu systemu.

07 / Ograniczenia

To rekonstrukcja historycznego przypadku, nie kontrolowany eksperyment.

Ustalenia dotyczą przede wszystkim struktury kodu, historii zmian i zachowanych dokumentów. Nie ma dowodu, że wadliwa ścieżka starszego systemu wykonała rzeczywiste zlecenie ani że spowodowała szkodę.

Nie zachowały się wszystkie historyczne rozmowy i decyzje. Dostępny materiał nie pozwala odtworzyć pełnej wiedzy ani motywacji uczestników.

Brak commitów w badanym repozytorium nie dowodzi braku aktywności we wszystkich powiązanych projektach.

Ograniczenia działającej trasy demonstracyjnej systemu-następcy zostały odrębnie potwierdzone. Nie zbadano pełnej skuteczności wszystkich zabezpieczeń nowego systemu.

08 / Od autora

Najbardziej wymownym elementem tej historii pozostaje dla mnie archiwizacja wyłącznika.

Zabezpieczenie można było usunąć z wykonywanej części systemu bez zmiany jej zachowania. To mocniejszy dowód braku integracji niż sama sprzeczność w dokumentacji.

Nie znam wszystkich przyczyn wcześniejszych decyzji i nie zamierzam ich dopowiadać. Zachowany kod wystarcza jednak do pokazania konkretnego defektu.

Wyłącznik nie musi być błędnie napisany, żeby nie chronił. Wystarczy, że system nigdy do niego nie dotrze.

Jak cytować

Bartłomiej Pietrzyk, „Wyłącznik awaryjny, którego nikt nie podłączył”
4digital Lab, 26.10.2026, https://lab.4digital.cloud/pl/wylacznik-awaryjny-ktorego-nikt-nie-podlaczyl/

Warunki wykorzystania opracowań i danych ustalane są indywidualnie.