Aktualna sytuacja: PHP2Shell. Dwie krytyczne luki w PHP (CVSS 9,2) umożliwiają wykonanie złośliwego kodu bez logowania. Poprawki od 21.10.2026.Co należy teraz zrobić →

Superglobals: $_GET, $_POST, $_FILES i inne

Superglobals to tablice, przez które kod PHP dostaje się do danych żądania. Kto wie, jak PHP je wypełnia i jakie obowiązują granice, pisze bezpieczniejszy kod i lepiej rozumie PHP2Shell.

Stan 4 min czytaniaWiedza o PHP

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ń:

  1. variables_order (domyślnie EGPCS) określa, które superglobals w ogóle są tworzone: Environment, GET, POST, Cookie, Server.
  2. request_order (domyślnie puste) określa, z czego powstaje $_REQUEST. Jeśli jest puste, obowiązuje variables_order. Dostarczane pliki php.ini pomijają według podręcznika cookies ze względów bezpieczeństwa.
  3. max_input_vars (domyślnie 1000) i max_input_nesting_level (domyślnie 64) ograniczają liczbę i zagnieżdżenie zmiennych wejściowych.
  4. post_max_size (domyślnie 8M) ogranicza zawartość żądania. Jeśli żądanie jest większe, $_POST i $_FILES pozostają puste.
  5. 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.

Działać natychmiast

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.

Źródła

Kontakt natychmiast

Liczy się każda godzina. Proszę napisać do nas teraz.

Proszę krótko opisać system, wersję PHP i obserwacje. Skontaktujemy się z Państwem, ustalimy sytuację i będziemy pracować zdalnie, aż incydent zostanie zamknięty i udokumentowany.

Natychmiastowa pomoc