Strona główna / Blog / containerd: obecny, nieuruchomiony

Blog · analiza

containerd jest w obrazie i SBOM-ie, ale podatny CRI nigdy się nie uruchamia: OpenShift pokazuje, jak „package present” może stworzyć finding poprawny technicznie i błędny operacyjnie

CVE-2026-53489 to podatność w plugin CRI containerd: przy przywracaniu logów kontenera z checkpoint image dochodzi do path traversal przez manipulację symlinkami (CWE-59, „Link Following”), co może odsłonić dowolne pliki hosta. CVSS 6.5, wektor AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N. Realna podatność. A mimo to dla wielu środowisk poprawny scanner wygeneruje finding, który jest technicznie prawdziwy i operacyjnie mylący.

Red Hat wprost wyjaśnia dlaczego: część produktów (OpenShift) używa jako container runtime CRI-O, a nie containerd. Niektóre obrazy zawierają moduł Go containerd jako build-time dependency do obsługi obrazów OCI, ale nie uruchamiają daemona containerd ani jego plugin CRI. Podatna ścieżka checkpoint-restore po prostu nie jest wykonywana.

containerd Go module w obrazie/SBOM → TAK daemon containerd uruchomiony → NIE (runtime = CRI-O) plugin CRI / checkpoint-restore path → nigdy nie wykonywany → vulnerable code not in execute path

Package present ≠ reachable vulnerable code

To jedno z najważniejszych rozróżnień nowoczesnego SCA. Skaner potrafi świetnie odpowiedzieć „czy ten komponent jest w obrazie?”, ale to nie jest pytanie o ryzyko. Pytania o ryzyko brzmią: czy podatny kod jest w ogóle wykonywany? czy istnieje ścieżka od wejścia atakującego do podatnej funkcji? czy komponent działa jako aktywny serwis, czy jest tylko biblioteką linkowaną „na zapas”? W przypadku containerd w OpenShift odpowiedź na wszystkie brzmi „nie” — mimo że komponent fizycznie jest w SBOM-ie.

To nie jest false positive

Kuszące jest zamknięcie takiego findingu jako „False Positive”. To błąd. Scanner nie pomylił się — containerd naprawdę jest w obrazie i naprawdę jest w podatnym zakresie. Lepszy opis stanu to:

correct component match: containerd obecny, wersja w podatnym zakresie.
but not reachable: daemon/CRI plugin nie jest wykonywany (runtime = CRI-O).
status: NOT_AFFECTED z justyfikacją, nie FALSE_POSITIVE.

Różnica ma znaczenie: „False Positive” sugeruje błąd detekcji i bywa nieodwracalne; „not affected, bo nieosiągalne” to decyzja z uzasadnieniem, którą można ponownie ocenić, jeśli zmieni się runtime.

To jest dokładnie miejsce na VEX

VEX (Vulnerability Exploitability eXchange) istnieje po to, by producent lub operator mógł powiedzieć nie tylko „komponent jest obecny”, ale „w tym kontekście podatny kod nie jest osiągalny”. Justyfikacja vulnerable_code_not_in_execute_path pasuje tu idealnie. Ale — jak zawsze przy VEX — dokument to tylko forma decyzji; ktoś musi wykazać, że daemon nie działa i że ścieżka checkpoint-restore nie jest wywoływana. Bez tego dowodu VEX zamienia się w wygodną wymówkę.

Uwaga na drugą stronę ostrza

Reachability zniżający ryzyko wymaga równie twardego dowodu, co reachability je podnoszący. „Nie używamy containerd daemon” jest prawdziwe dla OpenShift z CRI-O, ale byłoby fałszywe dla środowiska, które uruchamia containerd jako runtime. Ta sama biblioteka, ten sam CVE, inny deployment — inny werdykt. Dlatego status powinien mieć trigger ponownej oceny: recheck_on: runtime_changed. Jeśli ktoś jutro przełączy runtime na containerd, „not affected” przestaje być prawdą.

Co powinien zrobić Vulnerability Engineer?

  1. Ustal runtime każdego klastra/hosta: CRI-O czy containerd. To rozstrzyga osiągalność.
  2. Odróżnij „moduł Go w obrazie” od „uruchomionego daemona/plugin CRI”.
  3. Dla środowisk CRI-O oznacz finding jako NOT_AFFECTED z justyfikacją reachability i triggerem runtime_changed — nie jako False Positive.
  4. Dla środowisk faktycznie używających containerd — patchuj normalnie (podatny CRI checkpoint-restore jest osiągalny).
  5. Zapisz decyzję jako VEX z dowodem, nie samą deklaracją.

Wniosek

CVE-2026-53489 to modelowy przypadek, w którym poprawny scanner produkuje operacyjnie mylący finding. Komponent jest w SBOM-ie, wersja jest podatna — a mimo to podatny kod nie jest wykonywany, bo runtime to CRI-O. Dojrzały VM nie zamyka tego jako „False Positive” i nie eskaluje jako „Critical z obecności”, tylko rozstrzyga osiągalność i zapisuje decyzję jako VEX z dowodem i triggerem re-oceny. Pytanie brzmi nie „czy mamy containerd?”, tylko: czy podatny kod containerd jest w tym środowisku w ogóle wykonywany?

Powiązane na blogu

Źródła

Nota redakcyjna: stan informacji 31 sierpnia 2026. CVE-2026-53489 (CVSS 6.5, CWE-59) dotyczy path traversal przy przywracaniu logów z checkpoint image w plugin CRI containerd. Red Hat wskazuje, że dotknięte produkty używają CRI-O i zawierają containerd jako build-time dependency bez uruchamiania daemona/plugin CRI. Ocena osiągalności zależy od konkretnego środowiska.

Zapamiętaj jedno

Obecność komponentu w obrazie i SBOM-ie nie znaczy, że podatny kod jest osiągalny. Build-time dependency modułu Go to nie wykonywany daemon — to klasyczny przypadek na VEX not_affected: vulnerable_code_not_in_execute_path.