W typowym procesie VM historia kończy się szybko: skaner wykrywa CVE, producent wskazuje fixed version, zespół aktualizuje, finding znika z kolejnego skanu. pgAdmin 4 pokazuje, dlaczego taki model bywa zbyt prosty. Wersja 9.16 naprawiała m.in. SQL injection CVE-2026-12044, bypass read-only w AI Assistant CVE-2026-12045 oraz brak autoryzacji na endpointach SQL Editora CVE-2026-12046. W 9.17 projekt opublikował trzy kolejne CVE i przy każdym wprost zaznaczył, że to incomplete fix wcześniejszego problemu.
To nie jest ciekawostka dla researcherów. Dla Vulnerability Engineera to problem z wiarygodnością stanu Closed.
Pierwszy przypadek: SQL injection naprawione lokalnie, nie klasowo
CVE-2026-12044 obejmowało szereg miejsc, w których pgAdmin generował SQL z wartości wymagających prawidłowego escaping. W 9.16 poprawiono wiele template'ów i utwardzono określone sinki. W 9.17 pojawiło się CVE-2026-17346 — producent wyjaśnia, że wcześniejsza poprawka ominęła kolejne miejsca, które błędnie uznano za bezpieczne (PostgreSQL pozwala na nietypowe znaki w quoted identifiers, więc nazwa obiektu z apostrofem mogła ponownie wejść do nieescapowanej interpolacji). To różnica między naprawą konkretnego wystąpienia a naprawą klasy błędu. Jeżeli finding brzmi „SQL injection w template X”, łatwo poprawić template X — ale VE powinno zadać kolejne pytanie: gdzie jeszcze występuje ten sam sposób budowania zapytania?
Drugi przypadek: dwa parsery, dwie interpretacje bezpieczeństwa
CVE-2026-12045 dotyczyło AI Assistanta i mechanizmu ograniczającego wygenerowany SQL do transakcji read-only. W 9.17 CVE-2026-17351 pokazało lexer differential: sqlparse i PostgreSQL mogły inaczej interpretować ten sam fragment SQL przy określonej konfiguracji. Kontrola istniała — problem w tym, że oceniała inną semantykę danych niż komponent, który dane później wykonywał:
Ważna lekcja dla remediation verification: test starego PoC potwierdza tylko, że stary PoC już nie działa. Nie odpowiada, czy właściwość bezpieczeństwa zapewniono dla wszystkich równoważnych reprezentacji wejścia.
Trzeci przypadek: brakujący decorator znaleziono ponownie
CVE-2026-12046 naprawiało dwa endpointy pozbawione @pga_login_required. W 9.17 CVE-2026-17348 wskazało kolejne trasy w Constraints, Preferences, Debugger i Schema Diff z tym samym problemem. Jeżeli po znalezieniu pierwszego endpointu poprawiamy wyłącznie ten endpoint, wykonujemy bug fixing. Jeśli enumerujemy wszystkie endpointy i sprawdzamy je względem polityki autoryzacji, wykonujemy variant analysis — a to jest bliższe Vulnerability Engineering.
Czy administrator, który wdrożył 9.16, popełnił błąd?
Nie. W momencie, w którym vendor publikował 9.16 jako wersję z poprawkami, administrator miał racjonalne podstawy, by wdrożyć aktualizację i zamknąć findings. Problem pojawia się później, gdy nowy evidence zmienia stan wiedzy. Dlatego Fixed nie powinno być interpretowane jako wieczna prawda — lepszy model to fixed according to evidence available at time T. Po publikacji incomplete-fix CVE system powinien umieć odnaleźć assety, których wcześniejsze remediation zakończyło się na wersji obecnie uznanej za podatną.
Remediation lineage
Warto przechowywać relacje między podatnościami:
Dzięki temu można automatycznie znaleźć populację, w której finding dla parent CVE był zamknięty, asset nadal istnieje, a wersja jest affected przez follow-up CVE — i nadać jej stan REVALIDATION_REQUIRED. Nie trzeba fałszować historii przez zmianę starego Closed na Open: można zachować fakt, że wcześniejsza decyzja była poprawna według ówczesnej wiedzy, a jednocześnie uruchomić nową kampanię.
Trzy statusy zamiast dwóch
Nie każda podatność wymaga laboratoryjnego testu po patchu. Ale dla systemów krytycznych, exploitowanych CVE i przypadków incomplete fix taki model bywa znacznie wartościowszy niż proste Open/Closed.
Co powinien zrobić Vulnerability Engineer?
- Zidentyfikować wszystkie instancje poniżej 9.17, ze szczególnym uwzględnieniem 9.16.
- Wyszukać findings zamknięte wcześniej dla CVE-2026-12044, -12045 i -12046.
- Powiązać je z nowymi CVE (remediation lineage).
- Uwzględnić server mode, ekspozycję, model uwierzytelnienia i uprawnienia bazodanowe.
- Po aktualizacji potwierdzić nie tylko numer wersji, ale — tam gdzie ma to sens — oczekiwaną właściwość bezpieczeństwa.
Wniosek
pgAdmin 9.16 → 9.17 to bardzo dobry przykład, że Vulnerability Management nie kończy się na dopasowaniu wersji. Dobre VE śledzi historię poprawki, warianty tej samej klasy błędu i nowe dowody, które zmieniają ocenę wcześniejszego zamknięcia. Patch może być wdrożony poprawnie, a remediation nadal może wymagać ponownej walidacji. Liczba zamkniętych ticketów nie mówi jeszcze, czy remediation była trwała.
Powiązane na blogu
- Wazuh i „patched” ≠ „fixed” — incomplete fix i re-ewaluacja całej populacji
- libssh deklarował fix, którego nie zawierał — „fixed in” jako deklaracja, nie dowód
Źródła
- pgAdmin 4 v9.17 Release Notes (30.07.2026) — pgadmin.org
- pgAdmin 4 v9.16 Release Notes (18.06.2026) — pgadmin.org
- pgAdmin 4 v9.17 Released (31.07.2026) — pgadmin.org/news
Nota redakcyjna: stan informacji 1 września 2026. pgAdmin 9.17 opisuje CVE-2026-17346, CVE-2026-17348 i CVE-2026-17351 jako incomplete fixy odpowiednio CVE-2026-12044, CVE-2026-12046 i CVE-2026-12045 z 9.16. Artykuł koncentruje się na remediation lineage, variant analysis i modelu statusów, nie na eksploatacji.