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:
- Przeglądarka wysyła cookie z nazwą sesji, domyślnie
PHPSESSID. session_start()odczytuje ID i przekazuje je obsłudze przechowywania, domyślniefiles.- Obsługa ładuje zapisane dane, PHP przekształca je z powrotem przez
serialize_handleri wypełnia$_SESSION. - Skrypt czyta i zmienia
$_SESSIONjak zwykłą tablicę. - 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.