Kort gezegd: HTTP onthoudt tussen twee verzoeken niets. Een PHP-sessie lost dat op: PHP kent een willekeurig sessie-ID toe, stuurt het als cookie naar de browser en slaat de bijbehorende gegevens op de server op, standaard als bestand. Bij elk volgend verzoek leest session_start() de gegevens aan de hand van het ID weer in. Bij de PHP-sessie hoort ook de functie session.upload_progress, die php.net vanwege PHP2Shell adviseert tijdelijk aan de serverkant uit te schakelen.
Waarom webtoepassingen sessies nodig hebben
Elk verzoek aan een webserver staat op zichzelf. Zonder extra mechanisme zou een webshop bij de klik op „Winkelwagen” niet meer weten wie er net iets in heeft gelegd, en zou een beheerdersgedeelte bij elke klik om het wachtwoord moeten vragen. Sessies verbinden afzonderlijke verzoeken tot één sessie.
Voor beslissers betekent dat: het sessie-ID is na het inloggen evenveel waard als gebruikersnaam en wachtwoord samen. Voor beheerders betekent het: waar en hoe sessiegegevens staan, is een beveiligingsvraag, vooral op servers met meerdere websites.
Wat er bij session_start() gebeurt
Het verloop is bij elk verzoek gelijk en laat zich in vijf stappen beschrijven:
- De browser stuurt het cookie met de sessienaam mee, standaard
PHPSESSID. session_start()leest het ID en geeft het door aan de opslaghandler, standaardfiles.- De handler laadt de opgeslagen gegevens, PHP zet ze met de
serialize_handlerterug en vult$_SESSION. - Het script leest en wijzigt
$_SESSIONals een gewone array. - Aan het einde van het verzoek schrijft PHP de gegevens terug. Met
session.lazy_write(standaard: aan) alleen als ze zijn gewijzigd.
<?php
session_start();
$_SESSION['besuche'] = ($_SESSION['besuche'] ?? 0) + 1;
echo 'Seitenaufrufe in dieser Sitzung: ', (int) $_SESSION['besuche'];
Bestaat er nog geen sessie, dan maakt PHP een nieuw ID en zet het cookie. Is session.use_strict_mode actief, dan weigert PHP door de browser opgegeven, onbekende ID's en maakt een nieuw ID. De PHP-handleiding noemt deze instelling voor de elementaire beveiliging verplicht.
Standaardwaarden die men moet kennen
De volgende waarden gelden volgens de PHP-handleiding als er niets anders is geconfigureerd. Veel distributies en hosters stellen eigen waarden in, daarom telt altijd de daadwerkelijk werkzame configuratie.
| Instelling | Standaard | Betekenis |
|---|---|---|
session.save_handler |
files |
opslagplaats van de gegevens, ook Redis of database mogelijk |
session.name |
PHPSESSID |
naam van het cookie |
session.serialize_handler |
php |
formaat van de opgeslagen gegevens |
session.use_strict_mode |
0 |
onbekende ID's worden overgenomen |
session.use_only_cookies |
1 |
geen sessie-ID in het adres |
session.cookie_httponly |
0 |
JavaScript kan het cookie lezen |
session.cookie_secure |
0 |
cookie ook via onversleuteld HTTP |
session.cookie_samesite |
leeg | geen SameSite-attribuut |
session.gc_maxlifetime |
1440 |
seconden tot het mogelijke opruimen |
session.gc_probability / gc_divisor |
1 / 100 |
opruimen bij ongeveer elke honderdste start |
session.upload_progress.enabled |
1 |
uploadvoortgang wordt naar de sessie geschreven |
De waarden voor cookie_httponly, cookie_secure en use_strict_mode zijn af fabriek dus niet op beveiliging uitgelegd. Hoe u ze juist instelt, beschrijft de gids Sessies in PHP beveiligen. De instellingen session.sid_length en session.sid_bits_per_character zijn sinds PHP 8.4.0 als verouderd gemarkeerd.
Cookies direct instellen
Naast het sessiecookie kan een toepassing eigen cookies instellen. Sinds PHP 7.3.0 accepteert setcookie() daarvoor een array met opties, inclusief samesite. Sinds PHP 8.5.0 is er bovendien de optie partitioned.
<?php
setcookie('sprache', 'de', [
'expires' => time() + 60 * 60 * 24 * 30,
'path' => '/',
'secure' => true,
'httponly' => true,
'samesite' => 'Lax',
]);
Volgens de handleiding moet bij samesite gelijk aan None ook secure zijn ingesteld, anders blokkeert de browser het cookie. Cookies zijn gegevens van de browser: hun inhoud komt bij het volgende verzoek via $_COOKIE terug en moet als elke andere invoer worden gecontroleerd. Meer daarover op de pagina Superglobals.
session.upload_progress: voortgangsweergave voor uploads
PHP kan tijdens een bestandsupload de voortgang naar de sessie schrijven. Daarvoor stuurt het formulier een verborgen veld met de naam uit session.upload_progress.name, standaard PHP_SESSION_UPLOAD_PROGRESS. PHP legt de gegevens dan onder een sleutel met het voorvoegsel upload_progress_ in $_SESSION vast, met gegevens als starttijd, totale grootte en reeds verwerkte bytes.
Belangrijk voor het begrip: volgens de handleiding schrijft PHP deze informatie naar de sessie voordat enig script wordt uitgevoerd. De functie werkt dus tijdens de verwerking van het verzoek, nog vóór de toepassingscode. De instellingen ervan zijn van het type INI_PERDIR en zijn tijdens de uitvoering niet te wijzigen.
Sessies en PHP2Shell: de tussenmaatregel
Als een van de tussenmaatregelen tegen de PHP2Shell-lekken noemt php.net session.upload_progress.enabled=0 in te stellen in de php.ini, in de FPM-pool of in de serverconfiguratie en daarna alle workers opnieuw te starten, uitdrukkelijk niet via ini_set() of .user.ini. Op 23-10-2026 kwam de aanwijzing over CVE-2026-115560 erbij, met dezelfde oplossing tot de volgende reguliere bugfixrelease.
; FPM-pool van de website, daarna alle workers opnieuw starten
php_admin_flag[session.upload_progress.enabled] = off
Volgens vakberichten sluit deze instelling alleen niet beide lekken. Verplicht blijft de update naar PHP 8.5.12, 8.4.27, 8.3.36 of 8.2.35. Of uw toepassing de uploadvoortgang wel gebruikt en hoe u de instelling duurzaam instelt, beschrijft het artikel session.upload_progress uitschakelen.
Hoe helpt PHP SOS concreet?
- Wij lezen de daadwerkelijk werkzame sessie-instellingen per website uit, niet alleen de waarden van de opdrachtregel.
- Wij stellen de PHP2Shell-tussenmaatregelen per pool in, starten alle workers opnieuw en controleren het resultaat.
- Wij scheiden sessie-opslagplaatsen en pool-gebruikers tussen websites in het kader van de serverhardening.
- Na een incident vernietigen wij alle bestaande sessies, zodat gestolen sessie-ID's waardeloos worden.
Veelgestelde vragen
Wat is het verschil tussen cookie en sessie?
Een cookie is een kleine gegevensset die de browser opslaat en bij elk verzoek meestuurt. Een sessie slaat de eigenlijke gegevens op de server op; in het cookie staat alleen een willekeurige aanduiding, het sessie-ID.
Hoe lang leeft een PHP-sessie?
Het sessiecookie geldt standaard tot de browser wordt gesloten. De gegevens op de server mogen na session.gc_maxlifetime, standaard 1440 seconden zonder toegang, worden opgeruimd. Wanneer dat daadwerkelijk gebeurt, hangt af van de opruimlogica van het systeem.
Wat doet session.upload_progress?
De functie schrijft tijdens een bestandsupload de voortgang naar de sessie, zodat een tweede verzoek die kan tonen. Ze is standaard actief. Vanwege PHP2Shell adviseert php.net haar tijdelijk aan de serverkant uit te schakelen.
Is het genoeg om session.upload_progress met ini_set() uit te schakelen?
Nee. De instelling is volgens de handleiding sowieso niet tijdens de uitvoering te wijzigen, en php.net noemt uitdrukkelijk php.ini, FPM-pool of serverconfiguratie als juiste plaatsen, niet ini_set() of .user.ini. Start daarna alle workers opnieuw.