Current situation: PHP2Shell. Two critical PHP vulnerabilities (CVSS 9.2) allow malicious code without login. Patches since 21 October 2026.What to do now →

Superglobals: $_GET, $_POST, $_FILES and More

Superglobals are the arrays through which PHP code gets at request data. Knowing how PHP fills them and which limits apply leads to safer code and a better understanding of PHP2Shell.

Last updated 5 min readPHP knowledge

In short: Superglobals are predefined arrays that PHP fills automatically on every request and that are available everywhere in the code. $_GET contains the parameters from the address, $_POST the form data, $_FILES uploaded files, $_COOKIE the cookies and $_SERVER details about the request and server. PHP creates these arrays before your application code starts. That is why flaws in exactly this processing, as with PHP2Shell, cannot be caught by checks in the application.

What are superglobals?

In PHP, a variable normally applies only within the function in which it was created. Superglobals are the exception: they are available in every scope without having to fetch them with global. The PHP manual lists nine of them.

For non-technical readers this can be described as follows: the superglobals are the application's mailbox. Everything a visitor sends lands there before the application reads it. And everything in the mailbox potentially comes from a stranger.

The superglobals at a glance

Superglobal Content Origin
$_GET parameters from the address (query string) client
$_POST form fields of a POST request client
$_FILES details of uploaded files client, prepared by PHP
$_COOKIE cookies sent along by the browser client
$_REQUEST mixture of GET, POST and possibly cookies client
$_SERVER request headers, method, paths, server details web server and client mixed
$_ENV environment variables server
$_SESSION data of the current session server storage
$GLOBALS all global variables script

$_SERVER is particularly tricky. According to the manual, PHP creates an entry beginning with HTTP_ for every request header, such as HTTP_USER_AGENT. The client sets these values itself. According to the manual, SERVER_NAME can also contain the hostname supplied by the client and is not reliable for security decisions.

How PHP fills the superglobals

Before the first character of your script is executed, PHP has already been at work. It reads the address, the headers and the content of the request, breaks them down and places the results in the arrays. Several settings control this step:

  1. variables_order (default EGPCS) determines which superglobals are created at all: Environment, GET, POST, Cookie, Server.
  2. request_order (default empty) determines what $_REQUEST is built from. If it is empty, variables_order applies. According to the manual, the php.ini files shipped with PHP leave cookies out for security reasons.
  3. max_input_vars (default 1000) and max_input_nesting_level (default 64) limit the number and nesting depth of input variables.
  4. post_max_size (default 8M) limits the request body. If a request is larger, $_POST and $_FILES remain empty.
  5. enable_post_data_reading (default on) controls whether PHP automatically evaluates the content of POST requests at all.

If enable_post_data_reading is switched off, the application reads the raw content itself via php://input. Since PHP 8.4.0 there is additionally request_parse_body(), which also evaluates form and upload data for methods other than POST and allows its own limits. How the upload part works in detail is explained on the page How PHP processes file uploads.

Handling request data safely

The principle is simple: every value from $_GET, $_POST, $_COOKIE, $_FILES and the HTTP_ entries of $_SERVER is external input. It is validated on acceptance and escaped appropriately on output.

<?php
declare(strict_types=1);

// Integer expected: validate instead of converting blindly
$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');
}

// Allow only permitted values
$sortierung = in_array($_GET['sort'] ?? '', ['name', 'datum'], true)
    ? $_GET['sort']
    : 'datum';

// Always escape output
echo htmlspecialchars($_POST['kommentar'] ?? '', ENT_QUOTES, 'UTF-8');

A frequent stumbling block is information about where a request came from. If a reverse proxy, a load balancer or a CDN sits in front of the web server, $_SERVER['REMOTE_ADDR'] contains the address of that intermediary, not that of the visitor. The real address is then in a header such as X-Forwarded-For, which any client can set itself, though. The application may evaluate such headers only if the request demonstrably comes from its own known proxy. Otherwise, blocks by IP address or logs can easily be deceived. The same applies to HTTPS: if encryption ends at the proxy, the application must explicitly know that the original connection was encrypted.

Further patterns for validation and filtering are shown in the article Validating and filtering input in PHP. Session data in $_SESSION follows its own rules; they are on the page Sessions and cookies in PHP.

Superglobals and PHP2Shell: what happens before your code

This is where the link to the current situation lies. CVE-2026-109618 describes how an out-of-memory condition can interrupt PHP while request data is only partially initialised; during the clean-up of the request, invalid data can then be treated as valid. With CVE-2026-109619, internal state of a request can persist after its memory has been released and be used by a later request in the same worker.

Both flaws therefore lie in the processing that PHP itself performs around the request, not in the application code. The PHP team rates the risk highest for mod_php; an exploit was demonstrated there before any application code runs. No filter_var() and no check in the application can prevent that.

Act now

The update to PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35 and the restart of all PHP processes are mandatory. The interim measures from php.net, such as tighter limits for post_max_size, are not complete protection.

How does PHP SOS help?

  • We check the effective limits for request data per website and set them to suit the application.
  • We install the PHP update, restart all workers and document the patch level as part of our PHP patch service.
  • We examine custom developments to see whether values from superglobals reach the database, file system or output unchecked.
  • We secure the web server logs from 20 October 2026 onwards so that later analysis remains possible.

Frequently asked questions

How many superglobals are there in PHP?

The PHP manual lists nine: $GLOBALS, $_SERVER, $_GET, $_POST, $_FILES, $_COOKIE, $_SESSION, $_REQUEST and $_ENV. They are available in every scope, including inside functions and methods.

Can the values in $_SERVER be trusted?

Only partly. Entries beginning with HTTP_ come from the client's request headers. The manual warns, for example, that SERVER_NAME can reflect the hostname supplied by the client and is not reliable for security decisions.

Why is $_POST sometimes empty even though a form was submitted?

The most common cause is a request larger than post_max_size. In that case, according to the manual, $_POST and $_FILES remain empty. Switching off the setting enable_post_data_reading has the same effect.

Should I use $_REQUEST?

Better not. $_REQUEST mixes data from different sources, and which source wins depends on request_order and variables_order. Read values specifically from $_GET or $_POST.

Sources

Immediate contact

Every hour counts. Write to us now.

Briefly describe your system, PHP version and observation. We will get back to you, clarify the situation and work remotely until the incident is closed and documented.

Immediate help