Krótko: Superglobals to predefiniowane tablice, które PHP automatycznie wypełnia przy każdym żądaniu i które są dostępne w całym kodzie. $_GET zawiera parametry z adresu, $_POST dane formularzy, $_FILES przesłane pliki, $_COOKIE cookies, a $_SERVER informacje o żądaniu i serwerze. PHP tworzy te tablice, zanim wystartuje kod Państwa aplikacji. Dlatego luki właśnie w tym przetwarzaniu, jak w PHP2Shell, nie mogą zostać zatrzymane przez kontrole w aplikacji.
Czym są superglobals?
W PHP zmienna obowiązuje zwykle tylko w funkcji, w której ją utworzono. Superglobals to wyjątek: są dostępne w każdym zakresie widoczności, bez konieczności pobierania ich przez global. Podręcznik PHP wymienia dziewięć takich zmiennych.
Dla osób nietechnicznych można to opisać tak: superglobals to skrzynka pocztowa aplikacji. Wszystko, co wyśle odwiedzający, ląduje tam, zanim aplikacja to przeczyta. A wszystko w skrzynce pochodzi potencjalnie od obcego.
Superglobals w skrócie
| Superglobal | Zawartość | Pochodzenie |
|---|---|---|
$_GET |
parametry z adresu (query string) | klient |
$_POST |
pola formularza żądania POST | klient |
$_FILES |
dane o przesłanych plikach | klient, przygotowane przez PHP |
$_COOKIE |
cookies wysłane przez przeglądarkę | klient |
$_REQUEST |
mieszanka GET, POST i ewentualnie cookies | klient |
$_SERVER |
nagłówki żądania, metoda, ścieżki, dane serwera | serwer WWW i klient wymieszani |
$_ENV |
zmienne środowiskowe | serwer |
$_SESSION |
dane bieżącej sesji | pamięć serwera |
$GLOBALS |
wszystkie zmienne globalne | skrypt |
Szczególnie zdradliwy jest $_SERVER. Według podręcznika PHP tworzy dla każdego nagłówka żądania wpis z HTTP_ na początku, na przykład HTTP_USER_AGENT. Te wartości ustawia sam klient. Także SERVER_NAME może według podręcznika zawierać nazwę hosta podaną przez klienta i nie jest wiarygodna przy decyzjach dotyczących bezpieczeństwa.
Jak PHP wypełnia superglobals
Zanim zostanie wykonany pierwszy znak Państwa skryptu, PHP już pracowało. Czyta adres, nagłówki i zawartość żądania, rozbija je i zapisuje wyniki w tablicach. Ten krok steruje kilka ustawień:
variables_order(domyślnieEGPCS) określa, które superglobals w ogóle są tworzone: Environment, GET, POST, Cookie, Server.request_order(domyślnie puste) określa, z czego powstaje$_REQUEST. Jeśli jest puste, obowiązujevariables_order. Dostarczane pliki php.ini pomijają według podręcznika cookies ze względów bezpieczeństwa.max_input_vars(domyślnie1000) imax_input_nesting_level(domyślnie64) ograniczają liczbę i zagnieżdżenie zmiennych wejściowych.post_max_size(domyślnie8M) ogranicza zawartość żądania. Jeśli żądanie jest większe,$_POSTi$_FILESpozostają puste.enable_post_data_reading(domyślnie włączone) steruje tym, czy PHP w ogóle automatycznie przetwarza zawartość żądań POST.
Jeśli enable_post_data_reading jest wyłączone, aplikacja czyta surową zawartość sama przez php://input. Od PHP 8.4.0 istnieje dodatkowo request_parse_body(), które przetwarza dane formularzy i przesyłanych plików także dla innych metod niż POST i pozwala na własne wartości graniczne. Jak szczegółowo przebiega część dotycząca przesyłania plików, wyjaśnia strona Jak PHP przetwarza przesyłane pliki.
Bezpieczne postępowanie z danymi żądania
Zasada jest prosta: każda wartość z $_GET, $_POST, $_COOKIE, $_FILES i wpisów HTTP_ w $_SERVER to obce dane wejściowe. Sprawdza się ją przy przyjęciu i odpowiednio maskuje przy wyjściu.
<?php
declare(strict_types=1);
// Oczekiwana liczba całkowita: sprawdzić zamiast ślepo rzutować
$seite = filter_var($_GET['seite'] ?? '1', FILTER_VALIDATE_INT, [
'options' => ['min_range' => 1, 'max_range' => 500],
]);
if ($seite === false) {
http_response_code(400);
exit('Ungültige Seitenzahl');
}
// Dopuszczać tylko dozwolone wartości
$sortierung = in_array($_GET['sort'] ?? '', ['name', 'datum'], true)
? $_GET['sort']
: 'datum';
// Wyjście zawsze maskować
echo htmlspecialchars($_POST['kommentar'] ?? '', ENT_QUOTES, 'UTF-8');
Częstą pułapką są informacje o pochodzeniu żądania. Jeśli przed serwerem WWW stoi reverse proxy, load balancer lub CDN, $_SERVER['REMOTE_ADDR'] zawiera adres tego pośrednika, a nie odwiedzającego. Prawdziwy adres znajduje się wtedy w nagłówku takim jak X-Forwarded-For, który jednak każdy klient może ustawić sam. Aplikacja może interpretować takie nagłówki tylko wtedy, gdy żądanie dowodnie pochodzi z własnego, znanego proxy. W przeciwnym razie blokady według adresu IP lub dzienniki łatwo oszukać. Podobnie jest z HTTPS: jeśli szyfrowanie kończy się na proxy, aplikacja musi wyraźnie wiedzieć, że pierwotne połączenie było szyfrowane.
Dalsze wzorce walidacji i filtrowania pokazuje artykuł Walidacja i filtrowanie danych wejściowych w PHP. Dla danych sesji w $_SESSION obowiązują własne zasady; opisuje je strona Sesje i cookies w PHP.
Superglobals i PHP2Shell: co dzieje się przed Państwa kodem
Tu leży związek z obecną sytuacją. CVE-2026-109618 opisuje, że stan braku pamięci (out of memory) może przerwać PHP, gdy dane żądania są tylko częściowo zainicjowane; przy sprzątaniu żądania nieprawidłowe dane mogą zostać potraktowane jako prawidłowe. W przypadku CVE-2026-109619 wewnętrzny stan żądania może pozostać po zwolnieniu pamięci i zostać użyty przez późniejsze żądanie w tym samym workerze.
Obie luki tkwią więc w przetwarzaniu, które PHP samo wykonuje wokół żądania, a nie w kodzie aplikacji. Zespół PHP ocenia ryzyko przy mod_php jako najwyższe; pokazano tam exploit, zanim w ogóle zacznie działać kod aplikacji. Żadne filter_var() ani kontrola w aplikacji nie mogą temu zapobiec.
Obowiązkowa jest aktualizacja do PHP 8.5.12, 8.4.27, 8.3.36 lub 8.2.35 i restart wszystkich procesów PHP. Środki przejściowe z php.net, na przykład węższe granice dla post_max_size, nie są pełną ochroną.
Jak konkretnie pomaga PHP SOS?
- Sprawdzamy obowiązujące wartości graniczne dla danych żądania dla każdej strony i ustawiamy je odpowiednio do aplikacji.
- Instalujemy aktualizację PHP, restartujemy wszystkie workery i dokumentujemy stan poprawek w ramach naszej usługi PHP Patch Service.
- Sprawdzamy własne rozwiązania pod kątem tego, czy wartości z superglobals trafiają niesprawdzone do bazy danych, systemu plików lub wyjścia.
- Zabezpieczamy dzienniki serwera WWW od 20.10.2026, aby późniejsza analiza pozostała możliwa.
Częste pytania
Ile jest superglobals w PHP?
Podręcznik PHP wymienia dziewięć: $GLOBALS, $_SERVER, $_GET, $_POST, $_FILES, $_COOKIE, $_SESSION, $_REQUEST i $_ENV. Są dostępne w każdym zakresie widoczności, także w funkcjach i metodach.
Czy wartościom w $_SERVER można ufać?
Tylko częściowo. Wpisy zaczynające się od HTTP_ pochodzą z nagłówków żądania klienta. Podręcznik ostrzega na przykład, że SERVER_NAME może odzwierciedlać nazwę hosta podaną przez klienta i nie jest wiarygodna przy decyzjach dotyczących bezpieczeństwa.
Dlaczego $_POST bywa pusty, mimo że formularz został wysłany?
Najczęstszą przyczyną jest żądanie większe niż post_max_size. Wtedy $_POST i $_FILES pozostają według podręcznika puste. Prowadzi do tego także wyłączone ustawienie enable_post_data_reading.
Czy należy używać $_REQUEST?
Lepiej nie. $_REQUEST miesza dane z różnych źródeł, a to, które źródło wygrywa, zależy od request_order i variables_order. Wartości proszę odczytywać celowo z $_GET lub $_POST.