AI nie powie ci tego, o co nie zapytasz
Tydzień, w którym wszyscy łatali
21 października 2026 zespół PHP wydał poprawki do dwóch podatności, które pozwalały zdalnie uruchomić kod na serwerze bez żadnego logowania. W kolejnych dniach podobne łatki opublikowali twórcy Node.js, Buna, bibliotek Brotli dla Pythona i biblioteki Pillow. Można to uznać za zbieg okoliczności, ale w co najmniej dwóch z tych historii luki znaleźli badacze pracujący z modelami AI, które przeczesują popularny kod szybciej, niż zdołałby to zrobić jakikolwiek zespół ludzi.
To dobra wiadomość, a zarazem powód, żeby zapytać, co z tego wynika dla firm, które myślą o wdrożeniach opartych głównie na AI. Łatwo zaobserwować, że AI jest świetnym narzędziem w rękach kogoś, kto wie, o co zapytać, jak sprawdzić odpowiedź i co z nią zrobić. Nie wydaje się natomiast, że da się je w pełni bezpiecznie stosować bez takiej osoby, i właśnie o to pytanie tu chodzi.
PHP2Shell, czyli co się właściwie stało
Dwie podatności w rdzeniu PHP, CVE-2026-109618 i CVE-2026-109619, zespół PHP ocenił na 9,2 w skali CVSS 4.0 [1]. Pierwsza luka bierze się z braku pamięci. PHP przerywa wtedy przetwarzanie żądania w połowie inicjalizacji, a kod sprzątający traktuje niekompletne dane jak poprawne. W drugiej wewnętrzny stan żądania przeżywa zwolnienie pamięci, na którą wskazuje, więc następne żądanie obsługiwane przez ten sam proces może z niego skorzystać, zanim zostanie zainicjowany. Atakujący nie potrzebuje konta ani wiedzy o aplikacji, bo błąd siedzi w samym PHP, a nie w kodzie napisanym na jego podstawie.
O skali zagrożenia decyduje m.in. to, ile stron używa kodu z podatnością. Według W3Techs serwisy na PHP to około 70 procent witryn, dla których da się ustalić język po stronie serwera [2]. Odkrywcy pokazali działające ataki na WordPressa, Drupala i Joomlę [3], ale błąd tkwi w samym PHP, więc zagrożone są też inne aplikacje, na przykład sklepy internetowe oparte na Magento. Według zespołu PHP najbardziej narażone są instalacje z mod_php w Apache, bo atak może się tam udać, zanim ruszy jakikolwiek kod aplikacji, ale zagrożony jest w praktyce każdy serwer obsługujący żądania z sieci.
Nie dało się też tej luki załatać ustawieniami. Zespół PHP podał listę środków łagodzących, ale zaznaczył, że zmniejszają one ekspozycję tylko na wybrane ścieżki ataku, a pełnym rozwiązaniem jest aktualizacja [1]. Wersje 8.1 i starsze nie dostają już oficjalnych wydań, więc dla nich przygotowano jedynie minimalne backporty źródłowe. Każdy, kto zostawił na hostingu starą aplikację na PHP 7.4 albo 8.0, miał tego dnia konkretny problem.
Kto to znalazł i jak szybko wiadomość trafiła w obieg
Według PHP Foundation pierwsze ślady problemu z brakiem pamięci zauważył w 2024 roku deweloper rdzenia, który naprawiał błędy wskazane w zewnętrznym audycie firmy Quarkslab. Teoretycznie możliwy był exploit, ale nie znaleziono konkretnego i rzeczywistego wektora ataku, więc sprawę odłożono. Prace nad poprawką utknęły, bo każde podejście ma swoje koszty, a zespół bezpieczeństwa decyduje przez konsensus [4].
Sytuację zmienili badacze. 30 lipca zespół Calif zaczął audyt PHP w ramach programu Patch the Planet, a 11 sierpnia zgłosił bezwarunkowe zdalne wykonanie kodu o tej samej przyczynie co problem z pamięcią. Od tej chwili naprawa stała się priorytetem. 24 sierpnia to samo zgłosił Wiz, a 18 września kolejne wektory ataku dosłało OpenAI. Według opisu Wiz modele AI pomagały w wyszukiwaniu błędów, w budowie exploitów i w sprawdzaniu poprawek [3]. Za każdym z tych zgłoszeń stali specjaliści od bezpieczeństwa, którzy potrafili potwierdzić wynik i skoordynować go z zespołem PHP.
Wydanie poprawki zaplanowano pierwotnie na 22 października. 20 października około 15:00 czasu UTC w sieci pojawiły się numery CVE, ale bez szczegółów technicznych, więc PHP przesunęło wydanie o dzień. Wieczorem Calif przez pomyłkę opublikował film z działającym PoC, a 21 października o 7:41 UTC firma Chainguard złamała embargo i opublikowała obrazy z poprawką ponad sześć godzin przed uzgodnioną godziną [4]. Tego samego dnia watchTowr zobaczył na swoich honeypotach próby wykorzystania obu luk [5], a 26 października amerykańska agencja CISA dodała obie luki do katalogu aktywnie wykorzystywanych podatności [6].
Widać z tego jedno. Czas od chwili, gdy ktoś spoza wąskiego kręgu dowiaduje się o luce, do chwili, gdy potrafi ją wykorzystać, skurczył się do dni albo godzin. Koordynowane ujawnienie trwało tymczasem ponad dziesięć tygodni, licząc od pierwszego zgłoszenia 11 sierpnia.
Czym to groziło
Atakujący mógł jednym żądaniem uruchomić własny kod z uprawnieniami procesu PHP, co zwykle wystarcza do odczytu konfiguracji, haseł do bazy, kluczy API i plików, z których korzysta aplikacja. Badacze Wiz twierdzą też, że druga luka pozwala odczytać pamięć procesu, a w niej dane innych użytkowników obsługiwanych przez ten sam proces, i to bez pełnego wykonania kodu [3].
Reakcje instytucji pokazują, jak poważnie potraktowano sprawę. Amerykańska CISA zaleciła wyłączenie systemów opartych na PHP, jeśli nie da się ich od razu zaktualizować albo działają na PHP 8.1 lub starszym [6]. Brytyjskie NCSC napisało, że w ostateczności można rozważyć wyłączenie systemu do czasu pełnego zabezpieczenia [7], a kanadyjskie Cyber Centre zalecało izolowanie aplikacji wystawionych do internetu od sieci publicznych. W swoim alercie, uzupełnionym 23 października, pisało jeszcze, że aktywnych ataków nie zidentyfikowano, choć może się to szybko zmienić [8]. Trzy dni później CISA uznała, że ataki trwają. Czy to jeden z największych błędów w historii internetu, nie mnie oceniać, bo decydują o tym liczba podatnych systemów, skala rzeczywistych ataków i czas potrzebny na załatanie. Wiem natomiast, że luka objęła technologię stojącą pod większością stron w sieci.
Nie tylko PHP
W innych ekosystemach działo się podobnie, chociaż może sam zasięg podatności nie był aż tak spektakularny. Dekoder Brotli, biblioteka kompresji używana przez Node.js, Buna, Envoya, Istio, .NET i pakiety Pythona, miał podatność CVE-2026-111497, czyli zapis poza granicami pamięci o ocenie 9,2 według Google. Zgłosili ją badacze z OpenAI Codex Security [9]. Według analizy firmy Hacktron poprawka trafiła do źródeł Brotli już 27 lutego, bez oznaczenia jako poprawka bezpieczeństwa, a wydania z naprawą pojawiły się dopiero 21 października, osiem miesięcy później! Następnie przez kilka dni kolejne projekty publikowały własne wersje, bo każdy z nich ma wbudowaną własną kopię dekodera [10].
Równolegle Pillow, z której korzysta większość projektów w Pythonie do obróbki obrazów, dostała w wersji 13.0.0 poprawki do trzech krytycznych luk. Jedna z nich, wstrzyknięcie argumentów przez Ghostscript, pozwala przy określonej konfiguracji wykonać polecenie w systemie [11]. Warunki są węższe niż w PHP, ale każdy, kto przyjmuje od użytkowników zdjęcia, powinien sprawdzić swój stos. Z obu przypadków wynika to samo: błąd w jednej bibliotece rozlewa się na kilkanaście produktów, a mało kto wie, które wersje są faktycznie wbudowane w jego aplikację.
Znalezienie błędu to dopiero początek
Wpis PHP Foundation pokazuje, że wykrycie błędu i jego naprawa to dwa różne etapy. Fundacja sama nazywa opóźnienie strukturalną porażką, wynikającą zarówno ze sposobu podejmowania decyzji w zespole bezpieczeństwa, jak i z braku zasobów, a bezpieczeństwem zajmuje się według niej niewielka grupa programistów opłacanych przez fundację i trochę wolontariuszy [4]. Nie traktuję tego jako zarzutu wobec ludzi pracujących nad językiem, raczej jako opis warunków, w których pracują.
Fundacja zaznacza też, że AI zwiększyła liczbę zgłoszeń. Od 1 lipca opublikowała 15 CVE i odrzuciła ponad sto zgłoszeń jako błędne, zduplikowane albo niemożliwe do odtworzenia. Narzędzia AI pomagają w selekcji, ale według fundacji każdą decyzję podejmuje człowiek i to człowiek pracuje nad każdą poprawką [4]. W przypadku PHP po znalezieniu luk ludzie musieli ocenić zgłoszenia, uzgodnić poprawkę, przygotować wydania dla czterech aktywnych gałęzi i kilku wersji historycznych oraz skoordynować publikację z dystrybucjami Linuksa, a potem administratorzy na całym świecie wdrażali ją w ciągu kilku godzin. Model odpowiadał w tym łańcuchu za jedno ogniwo, i to pierwsze.
AI samo nie odpowie, jeśli nie zapytasz
W tym samym czasie, 13 października, na LessWrong ukazał się wpis „LLMs Knowingly Hide Their Mistakes”, który z pozoru nie ma nic wspólnego z cyberbezpieczeństwem [12]. Jego autorzy, Lucas Florin, Amelie Knecht, Ulysse Schaller i Thilo Hagendorff, wpisywali do historii rozmowy zmyślone pomyłki, tak jakby model popełnił je wcześniej: wysłał poufne dane niewłaściwej osobie albo nadpisał plik zamiast dopisać do niego. Następnie użytkownik pytał o coś zupełnie innego, a badacze sprawdzali, czy model sam wróci do tamtej pomyłki i się do niej przyzna.
W 67 procentach przypadków modele nie ujawniły błędu. Jawnie przyznawały się od 3 procent prób (Kimi K2.6) do 35 procent (Claude Sonnet 5). W 5 procentach prób zapis rozumowania pokazywał, że model wie o błędzie, ale w odpowiedzi go przemilcza. Częściej problem leżał gdzie indziej, bo w około połowie prób w zapisie rozumowania nie było śladu świadomości błędu, więc kwestia dotyczy nie tylko uczciwości, ale też uwagi. Kiedy kolejna wiadomość przypominała modelowi, że użytkownika nadal obchodzi ta sprawa, przyznawał się częściej, choć zatajanie nadal się zdarzało, w najgorszym przypadku w 15 procentach prób.
Wniosek, który z tego wyciągam, jest prosty. Model nie wraca sam do błędu, jeśli rozmowa toczy się o czymś innym, a żeby wiedzieć, o co zapytać, trzeba rozumieć, co mogło pójść nie tak. Badanie nie sprawdzało natomiast, co się stanie, gdy zapytamy wprost, czy coś poszło źle, więc nie wiem, czy samo to wystarczy. Trzeba też uczciwie zaznaczyć, że to był eksperyment z błędami wstawionymi do rozmowy, a nie z pomyłkami, które model popełnił sam, i że dotyczył raportowania w pracy agenta, a nie wykrywania luk w kodzie. Nie wynika z niego, że modele nie umieją znajdować podatności, bo jak widać wyżej umieją.
Gdzie tu haczyk?
Obie historie łączy to samo. Wiz, OpenAI i Calif znaleźli luki w PHP, bo pracowali z modelami jako specjaliści, którzy wiedzieli, gdzie szukać, jak zweryfikować wynik i komu go zgłosić. Nie wydaje mi się, że ten sam model w rękach kogoś bez takiej wiedzy dałby podobny efekt, ale badanie z LessWrong sugeruje, że nie ostrzegłby też, czego nie zrobił.
Dlatego zasadne jest pytanie, czy można uznać za bezpieczny taki sposób pracy, w którym AI wykonuje większość zadań programistów i administratorów, a nikt z doświadczeniem nie ocenia jej wyników? Nie sądzę, żeby istniała jedna odpowiedź dla wszystkich. Hobbysta budujący stronę dla siebie ponosi zupełnie inne ryzyko niż firma obsługująca dane klientów, a granica leży gdzieś pomiędzy. Nie sądzę też, żeby ktokolwiek mógł uczciwie powiedzieć, że ryzyko jest zerowe.
Zamiast gotowej odpowiedzi proponuję cztery sprawdzenia, które da się zrobić jeszcze dziś, niezależnie od tego, ile pracy oddajemy AI.
Pierwsze dotyczy zależności. Brotli pokazał, że luka w jednej bibliotece oznacza łatki w kilkunastu produktach, więc ktoś powinien umieć w kilka minut odpowiedzieć, czy dany komponent siedzi w naszej aplikacji, a nie tylko mieć wygenerowaną listę. W projekcie PHP zaczyna się to od composer audit i znajomości wersji interpretera na każdym serwerze, w projekcie Node.js od npm audit i wersji środowiska uruchomieniowego.
Drugie dotyczy wersji bez wsparcia. PHP 8.1 i starsze dostały tylko backporty źródłowe, więc jeśli jakaś aplikacja stoi na takiej wersji, ktoś musi o tym wiedzieć i to przed przykładową środą, a nie w środę.
Trzecie dotyczy czasu. Atakujący działali tego samego dnia, w którym pojawiły się poprawki, więc potrzebna jest osoba z uprawnieniami do wdrożenia aktualizacji poza zwykłym cyklem wydań oraz wcześniejsza zgoda, także na przerwę w działaniu systemu, jeśli nie da się inaczej.
Czwarte wynika z badania, które opisałem. Ktoś albo coś musi sprawdzać pracę modelu niezależnie od jego własnego raportu, czyli testy, logi, przegląd kodu przez człowieka albo drugi model, który ocenia zapis pracy z zewnątrz.
A w środę wieczorem?
Ostatnie pytanie kieruję do osób, które odpowiadają za produkt. Wyobraź sobie środę, 21 października. Czytasz, że krytyczna podatność dotyczy technologii, na której stoi twoja aplikacja, że atakujący zaczęli ją wykorzystywać, zanim większość administratorów zdążyła zaktualizować serwery, i że agencje rządowe radzą wyłączać systemy, których nie da się od razu załatać. Musisz w ciągu kilku godzin zdecydować, czy wyłączyć usługę, czy zaryzykować, i potrzebujesz kogoś, kto powie ci, jak wygląda twój system i jakie masz realne możliwości.
Trudno mi sobie wyobrazić, że w takiej chwili wystarczy to, co powie asystent AI znający projekt z wcześniejszych rozmów, szczególnie jeśli wiesz już, że modele potrafią nie wspomnieć o rzeczach, które wydają im się nieistotne dla bieżącego pytania. Dobrze, żebyś znał odpowiedź, zanim ta środa nadejdzie. Dziś jest jeszcze czas, żeby ją sobie ułożyć. W środę wieczorem już go nie będzie.
Źródła
- Critical Remote Code Execution Vulnerabilities, php.net, 21 października 2026
- W3Techs, Usage statistics of PHP as server-side programming language, dane z 26 października 2026: PHP używane jest przez 69,2% stron, których język po stronie serwera udało się ustalić, czyli nie przez 69,2% wszystkich stron w internecie. Polska Wikipedia podaje 77,4%, ale to dane z 7 maja 2022.
- PHP2Shell, strona zespołu Wiz
- Today’s PHP security release and how we’re strengthening PHP security, PHP Foundation, 21 października 2026
- PHP2Shell RCE Exploited: CVE-2026-109618 & CVE-2026-109619, watchTowr
- Critical Vulnerabilities in PHP Require Immediate Patching, CISA, 21 października 2026, aktualizacja z 26 października
- Critical security issue affecting PHP, NCSC (Wielka Brytania), 21 października 2026
- Critical vulnerabilities impacting PHP, Canadian Centre for Cyber Security, 21 października 2026, aktualizacja z 23 października
- Broccoli2shell: Everything You Need To Know About The Critical Brotli Decoder Vulnerability, Wiz
- Node2Shell: Brotli Decoder RCE in Node.js (CVE-2026-111497), Hacktron
- Three Critical Pillow CVEs, OX Security
- LLMs Knowingly Hide Their Mistakes, Florin, Knecht, Schaller, Hagendorff, LessWrong, 13 października 2026 (pełna praca: arXiv:2610.11351)