Kurz gesagt: Superglobals sind vordefinierte Arrays, die PHP bei jeder Anfrage automatisch befüllt und die überall im Code verfügbar sind. $_GET enthält die Parameter aus der Adresse, $_POST die Formulardaten, $_FILES hochgeladene Dateien, $_COOKIE die Cookies und $_SERVER Angaben zu Anfrage und Server. PHP erstellt diese Arrays, bevor Ihr Anwendungscode startet. Deshalb können Lücken in genau dieser Verarbeitung, wie bei PHP2Shell, nicht durch Prüfungen in der Anwendung abgefangen werden.
Was sind Superglobals?
In PHP gilt eine Variable normalerweise nur in der Funktion, in der sie angelegt wurde. Superglobals sind die Ausnahme: Sie stehen in jedem Gültigkeitsbereich zur Verfügung, ohne dass man sie mit global holen muss. Das PHP-Handbuch nennt neun davon.
Für Nicht-Techniker lässt sich das so beschreiben: Die Superglobals sind der Briefkasten der Anwendung. Alles, was ein Besucher schickt, landet dort, bevor die Anwendung es liest. Und alles im Briefkasten stammt potenziell von einem Fremden.
Die Superglobals im Überblick
| Superglobal | Inhalt | Herkunft |
|---|---|---|
$_GET |
Parameter aus der Adresse (Query-String) | Client |
$_POST |
Formularfelder einer POST-Anfrage | Client |
$_FILES |
Angaben zu hochgeladenen Dateien | Client, von PHP aufbereitet |
$_COOKIE |
vom Browser mitgeschickte Cookies | Client |
$_REQUEST |
Mischung aus GET, POST und gegebenenfalls Cookies | Client |
$_SERVER |
Anfrage-Header, Methode, Pfade, Serverangaben | Webserver und Client gemischt |
$_ENV |
Umgebungsvariablen | Server |
$_SESSION |
Daten der aktuellen Session | Server-Speicher |
$GLOBALS |
alle globalen Variablen | Skript |
Besonders tückisch ist $_SERVER. Laut Handbuch erzeugt PHP für jeden Anfrage-Header einen Eintrag mit HTTP_ am Anfang, etwa HTTP_USER_AGENT. Diese Werte setzt der Client selbst. Auch SERVER_NAME kann laut Handbuch den vom Client gelieferten Hostnamen enthalten und ist für Sicherheitsentscheidungen nicht verlässlich.
Wie PHP die Superglobals befüllt
Bevor das erste Zeichen Ihres Skripts ausgeführt wird, hat PHP bereits gearbeitet. Es liest die Adresse, die Header und den Inhalt der Anfrage, zerlegt sie und legt die Ergebnisse in die Arrays. Mehrere Einstellungen steuern diesen Schritt:
variables_order(StandardEGPCS) legt fest, welche Superglobals überhaupt angelegt werden: Environment, GET, POST, Cookie, Server.request_order(Standard leer) bestimmt, woraus$_REQUESTgebildet wird. Ist es leer, giltvariables_order. Die mitgelieferten php.ini-Dateien lassen Cookies laut Handbuch aus Sicherheitsgründen weg.max_input_vars(Standard1000) undmax_input_nesting_level(Standard64) begrenzen Anzahl und Verschachtelung der Eingabevariablen.post_max_size(Standard8M) begrenzt den Anfrageinhalt. Ist eine Anfrage größer, bleiben$_POSTund$_FILESleer.enable_post_data_reading(Standard an) steuert, ob PHP den Inhalt von POST-Anfragen überhaupt automatisch auswertet.
Ist enable_post_data_reading abgeschaltet, liest die Anwendung den rohen Inhalt selbst über php://input. Seit PHP 8.4.0 gibt es zusätzlich request_parse_body(), das Formular- und Upload-Daten auch für andere Methoden als POST auswertet und eigene Grenzwerte erlaubt. Wie der Upload-Teil im Detail abläuft, erklärt die Seite Wie PHP Datei-Uploads verarbeitet.
Sicher mit Anfragedaten umgehen
Der Grundsatz ist einfach: Jeder Wert aus $_GET, $_POST, $_COOKIE, $_FILES und den HTTP_-Einträgen von $_SERVER ist eine fremde Eingabe. Er wird bei der Annahme geprüft und bei der Ausgabe passend maskiert.
<?php
declare(strict_types=1);
// Ganzzahl erwartet: prüfen statt blind umwandeln
$seite = filter_var($_GET['seite'] ?? '1', FILTER_VALIDATE_INT, [
'options' => ['min_range' => 1, 'max_range' => 500],
]);
if ($seite === false) {
http_response_code(400);
exit('Ungültige Seitenzahl');
}
// Nur erlaubte Werte zulassen
$sortierung = in_array($_GET['sort'] ?? '', ['name', 'datum'], true)
? $_GET['sort']
: 'datum';
// Ausgabe immer maskieren
echo htmlspecialchars($_POST['kommentar'] ?? '', ENT_QUOTES, 'UTF-8');
Ein häufiger Stolperstein sind Angaben zur Herkunft einer Anfrage. Steht vor dem Webserver ein Reverse Proxy, ein Load Balancer oder ein CDN, enthält $_SERVER['REMOTE_ADDR'] die Adresse dieses Vermittlers, nicht die des Besuchers. Die echte Adresse steht dann in einem Header wie X-Forwarded-For, den aber jeder Client selbst setzen kann. Die Anwendung darf solche Header nur auswerten, wenn die Anfrage nachweislich von einem eigenen, bekannten Proxy kommt. Sonst lassen sich Sperren nach IP-Adresse oder Protokolle leicht täuschen. Ähnliches gilt für HTTPS: Endet die Verschlüsselung am Proxy, muss die Anwendung ausdrücklich wissen, dass die ursprüngliche Verbindung verschlüsselt war.
Weitere Muster für Validierung und Filterung zeigt der Beitrag Eingaben in PHP validieren und filtern. Für Sitzungsdaten in $_SESSION gelten eigene Regeln; sie stehen auf der Seite Sessions und Cookies in PHP.
Superglobals und PHP2Shell: Was vor Ihrem Code passiert
Hier liegt der Bezug zur aktuellen Lage. CVE-2026-109618 beschreibt, dass ein Out-of-Memory-Zustand PHP unterbrechen kann, während Anfragedaten nur teilweise initialisiert sind; beim Aufräumen der Anfrage können ungültige Daten dann als gültig behandelt werden. Bei CVE-2026-109619 kann interner Zustand einer Anfrage nach dem Freigeben des Speichers bestehen bleiben und von einer späteren Anfrage im selben Worker genutzt werden.
Beide Lücken liegen also in der Verarbeitung, die PHP selbst rund um die Anfrage leistet, nicht im Anwendungscode. Das PHP-Team stuft das Risiko bei mod_php am höchsten ein; dort wurde ein Exploit gezeigt, bevor überhaupt Anwendungscode läuft. Kein filter_var() und keine Prüfung in der Anwendung kann das verhindern.
Pflicht ist das Update auf PHP 8.5.12, 8.4.27, 8.3.36 oder 8.2.35 und der Neustart aller PHP-Prozesse. Die Übergangsmaßnahmen von php.net, etwa engere Grenzen für post_max_size, sind kein vollständiger Schutz.
Wie hilft PHP SOS konkret?
- Wir prüfen die wirksamen Grenzwerte für Anfragedaten je Website und setzen sie passend zur Anwendung.
- Wir spielen das PHP-Update ein, starten alle Worker neu und belegen den Patchstand im Rahmen unseres PHP-Patch-Service.
- Wir prüfen Eigenentwicklungen darauf, ob Werte aus Superglobals ungeprüft in Datenbank, Dateisystem oder Ausgabe gelangen.
- Wir sichern die Webserver-Logs ab dem 20.10.2026, damit eine spätere Auswertung möglich bleibt.
Häufige Fragen
Wie viele Superglobals gibt es in PHP?
Das PHP-Handbuch nennt neun: $GLOBALS, $_SERVER, $_GET, $_POST, $_FILES, $_COOKIE, $_SESSION, $_REQUEST und $_ENV. Sie sind in jedem Gültigkeitsbereich verfügbar, auch in Funktionen und Methoden.
Sind Werte in $_SERVER vertrauenswürdig?
Nur teilweise. Einträge mit HTTP_ am Anfang stammen aus den Anfrage-Headern des Clients. Das Handbuch warnt zum Beispiel, dass SERVER_NAME den vom Client gelieferten Hostnamen widerspiegeln kann und für Sicherheitsentscheidungen nicht verlässlich ist.
Warum ist $_POST manchmal leer, obwohl ein Formular gesendet wurde?
Häufigste Ursache ist eine Anfrage, die größer als post_max_size ist. Dann bleiben $_POST und $_FILES laut Handbuch leer. Auch eine abgeschaltete Einstellung enable_post_data_reading führt dazu.
Sollte man $_REQUEST verwenden?
Besser nicht. $_REQUEST mischt Daten aus verschiedenen Quellen, und welche Quelle gewinnt, hängt von request_order und variables_order ab. Lesen Sie Werte gezielt aus $_GET oder $_POST.