# Sessioner og cookies i PHP

> Sådan fungerer PHP-sessioner og cookies: session-ID, lagring, standardværdier i php.ini, upload-fremskridt og overgangsforanstaltningen mod PHP2Shell.

Kilde: https://phpsos.de/da/php/sessions-und-cookies/  
Status: 25.10.2026  
Udbyder: PHP SOS, PHP-nødhjælp og serversikkerhed. Akut hjælp på WhatsApp: https://wa.me/491736494914?text=Hej%20PHP%20SOS%2C%20vi%20har%20brug%20for%20hj%C3%A6lp%20med%20vores%20PHP-server.%20Firma%3A%20%E2%80%A6%20Website%3A%20%E2%80%A6

**Kort sagt:** HTTP husker intet mellem to forespørgsler. En PHP-session løser det: PHP tildeler et tilfældigt session-ID, sender det som cookie til browseren og gemmer de tilhørende data på serveren, som standard som fil. Ved hver yderligere forespørgsel læser `session_start()` dataene ind igen ud fra ID'et. Til PHP-sessionen hører også funktionen `session.upload_progress`, som php.net på grund af PHP2Shell anbefaler midlertidigt at slå fra på serversiden.

## Hvorfor webapplikationer har brug for sessioner

Hver forespørgsel til en webserver står for sig. Uden en ekstra mekanisme ville en shop ved klik på "Indkøbskurv" ikke længere vide, hvem der lige har lagt noget i den, og et administrationsområde skulle spørge efter adgangskoden ved hvert klik. Sessioner forbinder enkelte forespørgsler til en sidde.

For beslutningstagere betyder det: Session-ID'et er efter login lige så meget værd som brugernavn og adgangskode tilsammen. For administratorer betyder det: Hvor og hvordan sessionsdata ligger, er et sikkerhedsspørgsmål, især på servere med flere websites.

## Hvad der sker ved session_start()

Forløbet er ved hver forespørgsel det samme og kan beskrives i fem trin:

1. Browseren sender cookien med sessionens navn med, som standard `PHPSESSID`.
2. `session_start()` læser ID'et og overdrager det til lager-handleren, som standard `files`.
3. Handleren indlæser de gemte data, PHP omdanner dem med `serialize_handler` tilbage og udfylder `$_SESSION`.
4. Scriptet læser og ændrer `$_SESSION` som et almindeligt array.
5. Ved forespørgslens slutning skriver PHP dataene tilbage. Med `session.lazy_write` (standard: til) kun hvis de er ændret.

```php
<?php
session_start();

$_SESSION['besuche'] = ($_SESSION['besuche'] ?? 0) + 1;
echo 'Seitenaufrufe in dieser Sitzung: ', (int) $_SESSION['besuche'];
```

Findes der endnu ingen session, opretter PHP et nyt ID og sætter cookien. Er `session.use_strict_mode` aktiv, afviser PHP ukendte ID'er, som browseren foreskriver, og opretter et nyt. PHP-manualen betegner denne indstilling som tvingende nødvendig for den grundlæggende sikkerhed.

## Standardværdier, man bør kende

De følgende værdier gælder ifølge PHP-manualen, hvis intet andet er konfigureret. Mange distributioner og hostere sætter egne værdier, derfor tæller altid den faktisk virksomme konfiguration.

| Indstilling | Standard | Betydning |
|---|---|---|
| `session.save_handler` | `files` | lagringssted for dataene, også Redis eller database er mulig |
| `session.name` | `PHPSESSID` | cookiens navn |
| `session.serialize_handler` | `php` | format for de gemte data |
| `session.use_strict_mode` | `0` | ukendte ID'er overtages |
| `session.use_only_cookies` | `1` | intet session-ID i adressen |
| `session.cookie_httponly` | `0` | JavaScript kan læse cookien |
| `session.cookie_secure` | `0` | cookie også over ukrypteret HTTP |
| `session.cookie_samesite` | tom | ingen SameSite-attribut |
| `session.gc_maxlifetime` | `1440` | sekunder indtil mulig oprydning |
| `session.gc_probability` / `gc_divisor` | `1` / `100` | oprydning ved ca. hver hundrede start |
| `session.upload_progress.enabled` | `1` | upload-fremskridt skrives ind i sessionen |

Værdierne for `cookie_httponly`, `cookie_secure` og `use_strict_mode` er altså fra fabrikken ikke udlagt til sikkerhed. Hvordan I sætter dem rigtigt, beskriver guiden [Sikring af sessioner i PHP](https://phpsos.de/da/ratgeber/session-sicherheit-php/). Indstillingerne `session.sid_length` og `session.sid_bits_per_character` er siden PHP 8.4.0 markeret som forældede.

## Sætte cookies direkte

Ved siden af session-cookien kan en applikation sætte egne cookies. Siden PHP 7.3.0 tager `setcookie()` hertil et array med indstillinger, herunder `samesite`. Siden PHP 8.5.0 findes desuden indstillingen `partitioned`.

```php
<?php
setcookie('sprache', 'de', [
    'expires'  => time() + 60 * 60 * 24 * 30,
    'path'     => '/',
    'secure'   => true,
    'httponly' => true,
    'samesite' => 'Lax',
]);
```

Ifølge manualen skal ved `samesite` lig `None` også `secure` være sat, ellers blokerer browseren cookien. Cookies er browserens data: Deres indhold kommer ved næste forespørgsel tilbage via `$_COOKIE` og skal kontrolleres som ethvert andet input. Mere herom på siden [Superglobals](https://phpsos.de/da/php/superglobals/).

## session.upload_progress: fremskridtsvisning til uploads

PHP kan under en filupload skrive fremskridtet ind i sessionen. Hertil sender formularen et skjult felt med navnet fra `session.upload_progress.name`, som standard `PHP_SESSION_UPLOAD_PROGRESS`. PHP lægger så dataene under en nøgle med præfikset `upload_progress_` i `$_SESSION`, med oplysninger som starttidspunkt, samlet størrelse og allerede behandlede bytes.

Vigtigt for forståelsen: Ifølge manualen skriver PHP disse oplysninger ind i sessionen, før noget script udføres. Funktionen arbejder altså under behandlingen af forespørgslen, endnu før applikationskoden. Dens indstillinger er af typen `INI_PERDIR` og kan ikke ændres under kørsel.

## Sessioner og PHP2Shell: overgangsforanstaltningen

Som en af overgangsforanstaltningerne mod PHP2Shell-sårbarhederne nævner php.net at sætte `session.upload_progress.enabled=0` i php.ini, i FPM-poolen eller i serverkonfigurationen og derefter genstarte alle workere, udtrykkeligt ikke via `ini_set()` eller `.user.ini`. Den 23.10.2026 kom henvisningen til [CVE-2026-115560](https://phpsos.de/da/php2shell/cve-2026-115560/) til, med den samme afhjælpning indtil den næste ordinære bugfix-udgivelse.

```ini
; FPM-pool for websitet, derefter genstart alle workere
php_admin_flag[session.upload_progress.enabled] = off
```

Ifølge fagrapporter lukker denne indstilling alene ikke begge sårbarheder. Pligt forbliver opdateringen til PHP 8.5.12, 8.4.27, 8.3.36 eller 8.2.35. Om jeres applikation overhovedet bruger upload-fremskridtet, og hvordan I sætter indstillingen varigt, beskriver indlægget [Slå session.upload_progress fra](https://phpsos.de/da/blog/session-upload-progress-abschalten/).

## Hvordan hjælper PHP SOS konkret?

- Vi aflæser de faktisk virksomme sessionsindstillinger pr. website, ikke blot værdierne fra kommandolinjen.
- Vi sætter PHP2Shell-overgangsforanstaltningerne pr. pool, genstarter alle workere og kontrollerer resultatet.
- Vi adskiller sessionslagringssteder og pool-brugere mellem websites som led i [serverhærdningen](https://phpsos.de/da/leistungen/server-haertung/).
- Efter en hændelse kasserer vi alle bestående sessioner, så stjålne session-ID'er bliver værdiløse.


## Ofte stillede spørgsmål

**Hvad er forskellen på cookie og session?**  
En cookie er en lille datapost, som browseren gemmer og sender med ved hver forespørgsel. En session gemmer de egentlige data på serveren; i cookien står kun en tilfældig identifikator, session-ID'et.

**Hvor længe lever en PHP-session?**  
Session-cookien gælder som standard, indtil browseren lukkes. Dataene på serveren må ryddes op efter session.gc_maxlifetime, som standard 1440 sekunder uden adgang. Hvornår det faktisk sker, afhænger af systemets oprydningslogik.

**Hvad gør session.upload_progress?**  
Funktionen skriver under en filupload fremskridtet ind i sessionen, så en anden forespørgsel kan vise det. Den er aktiv som standard. På grund af PHP2Shell anbefaler php.net midlertidigt at slå den fra på serversiden.

**Er det nok at slå session.upload_progress fra via ini_set()?**  
Nej. Indstillingen kan ifølge manualen alligevel ikke ændres under kørsel, og php.net nævner udtrykkeligt php.ini, FPM-pool eller serverkonfiguration som de rigtige steder, ikke ini_set() eller .user.ini. Genstart derefter alle workere.

## Kilder

- [PHP-manualen: Sessionskonfiguration](https://www.php.net/manual/de/session.configuration.php)
- [PHP-manualen: Sessionens upload-fremskridt](https://www.php.net/manual/de/session.upload-progress.php)
- [PHP-manualen: setcookie](https://www.php.net/manual/en/function.setcookie.php)
- [php.net: Sikkerhedsmeddelelser](https://www.php.net/)
