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ć →

Sesje i cookies w PHP

Sesje czynią z bezstanowego HTTP logowanie, które trwa przez kilka stron. Oto jak PHP rozwiązuje to wewnętrznie, jakie wartości domyślne obowiązują i co session.upload_progress ma wspólnego z PHP2Shell.

Stan 4 min czytaniaWiedza o PHP

Krótko: HTTP nie pamięta niczego między dwoma żądaniami. Sesja PHP rozwiązuje ten problem: PHP nadaje losowe ID sesji, wysyła je jako cookie do przeglądarki i zapisuje powiązane dane na serwerze, domyślnie jako plik. Przy każdym kolejnym żądaniu session_start() odczytuje dane ponownie na podstawie ID. Do sesji PHP należy także funkcja session.upload_progress, którą php.net z powodu PHP2Shell zaleca tymczasowo wyłączyć po stronie serwera.

Dlaczego aplikacje internetowe potrzebują sesji

Każde żądanie do serwera WWW stoi samo za siebie. Bez dodatkowego mechanizmu sklep nie wiedziałby po kliknięciu „Koszyk”, kto przed chwilą coś do niego włożył, a obszar administracyjny musiałby przy każdym kliknięciu pytać o hasło. Sesje łączą pojedyncze żądania w jedną sesję.

Dla osób podejmujących decyzje oznacza to: ID sesji jest po zalogowaniu tyle warte, co nazwa użytkownika i hasło razem. Dla administratorów oznacza to: gdzie i jak leżą dane sesji, to kwestia bezpieczeństwa, zwłaszcza na serwerach z wieloma stronami.

Co dzieje się przy session_start()

Przebieg jest przy każdym żądaniu taki sam i można go opisać w pięciu krokach:

  1. Przeglądarka wysyła cookie z nazwą sesji, domyślnie PHPSESSID.
  2. session_start() odczytuje ID i przekazuje je obsłudze przechowywania, domyślnie files.
  3. Obsługa ładuje zapisane dane, PHP przekształca je z powrotem przez serialize_handler i wypełnia $_SESSION.
  4. Skrypt czyta i zmienia $_SESSION jak zwykłą tablicę.
  5. Na końcu żądania PHP zapisuje dane z powrotem. Przy session.lazy_write (domyślnie: włączone) tylko wtedy, gdy się zmieniły.
<?php
session_start();

$_SESSION['besuche'] = ($_SESSION['besuche'] ?? 0) + 1;
echo 'Seitenaufrufe in dieser Sitzung: ', (int) $_SESSION['besuche'];

Jeśli sesji jeszcze nie ma, PHP tworzy nowe ID i ustawia cookie. Jeśli session.use_strict_mode jest aktywne, PHP odrzuca nieznane ID narzucone przez przeglądarkę i tworzy nowe. Podręcznik PHP określa to ustawienie dla podstawowego bezpieczeństwa jako obowiązkowe.

Wartości domyślne, które warto znać

Poniższe wartości obowiązują według podręcznika PHP, jeśli nie skonfigurowano inaczej. Wiele dystrybucji i dostawców hostingu ustawia własne wartości, dlatego zawsze liczy się faktycznie obowiązująca konfiguracja.

Ustawienie Domyślnie Znaczenie
session.save_handler files miejsce zapisu danych, możliwe także Redis lub baza danych
session.name PHPSESSID nazwa cookie
session.serialize_handler php format zapisanych danych
session.use_strict_mode 0 nieznane ID są przyjmowane
session.use_only_cookies 1 brak ID sesji w adresie
session.cookie_httponly 0 JavaScript może odczytać cookie
session.cookie_secure 0 cookie także przez nieszyfrowane HTTP
session.cookie_samesite puste brak atrybutu SameSite
session.gc_maxlifetime 1440 sekundy do możliwego sprzątania
session.gc_probability / gc_divisor 1 / 100 sprzątanie mniej więcej przy co setnym starcie
session.upload_progress.enabled 1 postęp przesyłania jest zapisywany w sesji

Wartości cookie_httponly, cookie_secure i use_strict_mode nie są więc fabrycznie nastawione na bezpieczeństwo. Jak je prawidłowo ustawić, opisuje poradnik Zabezpieczanie sesji w PHP. Ustawienia session.sid_length i session.sid_bits_per_character są od PHP 8.4.0 oznaczone jako przestarzałe.

Bezpośrednie ustawianie cookies

Oprócz cookie sesji aplikacja może ustawiać własne cookies. Od PHP 7.3.0 setcookie() przyjmuje w tym celu tablicę z opcjami, w tym samesite. Od PHP 8.5.0 dochodzi dodatkowo opcja partitioned.

<?php
setcookie('sprache', 'de', [
    'expires'  => time() + 60 * 60 * 24 * 30,
    'path'     => '/',
    'secure'   => true,
    'httponly' => true,
    'samesite' => 'Lax',
]);

Według podręcznika przy samesite równym None musi być ustawione także secure, w przeciwnym razie przeglądarka blokuje cookie. Cookies to dane przeglądarki: ich zawartość wraca przy następnym żądaniu przez $_COOKIE i musi być sprawdzana jak każde inne dane wejściowe. Więcej na stronie Superglobals.

session.upload_progress: wskaźnik postępu przesyłania

PHP może w czasie przesyłania pliku zapisywać postęp w sesji. W tym celu formularz wysyła ukryte pole o nazwie z session.upload_progress.name, domyślnie PHP_SESSION_UPLOAD_PROGRESS. PHP zapisuje wtedy dane w $_SESSION pod kluczem z prefiksem upload_progress_, z informacjami takimi jak czas startu, rozmiar całkowity i liczba już przetworzonych bajtów.

Ważne dla zrozumienia: według podręcznika PHP zapisuje te informacje w sesji, zanim zostanie wykonany jakikolwiek skrypt. Funkcja działa więc podczas przetwarzania żądania, jeszcze przed kodem aplikacji. Jej ustawienia są typu INI_PERDIR i nie da się ich zmienić w czasie działania.

Sesje i PHP2Shell: środek przejściowy

Jako jeden ze środków przejściowych przeciw lukom PHP2Shell php.net podaje ustawienie session.upload_progress.enabled=0 w php.ini, w puli FPM lub w konfiguracji serwera, a następnie restart wszystkich workerów, wyraźnie nie przez ini_set() ani .user.ini. W dniu 23.10.2026 doszła wskazówka dotycząca CVE-2026-115560, z tym samym środkiem zaradczym do następnego regularnego wydania poprawkowego.

; Pula FPM strony, potem zrestartować wszystkie workery
php_admin_flag[session.upload_progress.enabled] = off

Według doniesień branżowych samo to ustawienie nie zamyka obu luk. Obowiązkowa pozostaje aktualizacja do PHP 8.5.12, 8.4.27, 8.3.36 lub 8.2.35. To, czy Państwa aplikacja w ogóle używa postępu przesyłania i jak ustawić to trwale, opisuje artykuł Wyłączanie session.upload_progress.

Jak konkretnie pomaga PHP SOS?

  • Odczytujemy faktycznie obowiązujące ustawienia sesji dla każdej strony, a nie tylko wartości wiersza poleceń.
  • Ustawiamy środki przejściowe PHP2Shell dla każdej puli, restartujemy wszystkie workery i sprawdzamy wynik.
  • Rozdzielamy miejsca przechowywania sesji i użytkowników pul między stronami w ramach utwardzania serwera.
  • Po incydencie unieważniamy wszystkie istniejące sesje, aby skradzione ID sesji straciły wartość.

Częste pytania

Jaka jest różnica między cookie a sesją?

Cookie to mały zestaw danych, który przeglądarka zapisuje i wysyła przy każdym żądaniu. Sesja przechowuje właściwe dane na serwerze; w cookie znajduje się tylko losowy identyfikator, czyli ID sesji.

Jak długo żyje sesja PHP?

Cookie sesji obowiązuje domyślnie do zamknięcia przeglądarki. Dane na serwerze mogą być sprzątane po session.gc_maxlifetime, domyślnie po 1440 sekundach bez dostępu. To, kiedy faktycznie się to dzieje, zależy od logiki sprzątania w systemie.

Co robi session.upload_progress?

Funkcja zapisuje w czasie przesyłania pliku postęp w sesji, aby drugie żądanie mogło go wyświetlić. Jest domyślnie aktywna. Z powodu PHP2Shell php.net zaleca tymczasowo wyłączyć ją po stronie serwera.

Czy wystarczy wyłączyć session.upload_progress przez ini_set()?

Nie. Ustawienia tego według podręcznika i tak nie da się zmienić w czasie działania, a php.net wyraźnie wymienia jako właściwe miejsca php.ini, pulę FPM lub konfigurację serwera, a nie ini_set() czy .user.ini. Potem zrestartować wszystkie workery.

Ź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