Actuele situatie: PHP2Shell. Twee kritieke PHP-kwetsbaarheden (CVSS 9.2) maken schadelijke code zonder inloggen mogelijk. Patches sinds 21-10-2026.Wat u nu moet doen →

Sessies en cookies in PHP

Sessies maken van het toestandsloze HTTP een aanmelding die over meerdere pagina's standhoudt. Hier staat hoe PHP dat intern oplost, welke standaardwaarden gelden en wat session.upload_progress met PHP2Shell te maken heeft.

Stand 5 min. leestijdPHP-kennis

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:

  1. De browser stuurt het cookie met de sessienaam mee, standaard PHPSESSID.
  2. session_start() leest het ID en geeft het door aan de opslaghandler, standaard files.
  3. De handler laadt de opgeslagen gegevens, PHP zet ze met de serialize_handler terug en vult $_SESSION.
  4. Het script leest en wijzigt $_SESSION als een gewone array.
  5. 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.

Bronnen

Direct contact

Elk uur telt. Schrijf ons nu.

Beschrijf kort het systeem, de PHP-versie en wat u opmerkt. Wij nemen contact op, brengen de situatie in kaart en werken op afstand tot het incident is afgerond en gedocumenteerd.

Directe hulp