PHP.GT

Whitelisting superglobals

Whitelisting lets us keep a small number of known-safe offsets available while still blocking everything else.

This is useful when a tool expects one specific cookie, environment variable, or server key to remain readable, but we still want the rest of the superglobal to be protected.

The whitelist shape

The second argument to removeGlobals() is an associative array.

  • The keys are superglobal names such as "_COOKIE" or "_SERVER".
  • The values are lists of offsets that should remain available within that superglobal.

Example:

$whiteList = [
	"_COOKIE" => ["XDEBUG_SESSION"],
	"_SERVER" => ["REQUEST_TIME_FLOAT"],
];

Passing the whitelist to removeGlobals()

$allowed = $protection->removeGlobals(
	[
		"_COOKIE" => $_COOKIE,
		"_SERVER" => $_SERVER,
	],
	[
		"_COOKIE" => ["XDEBUG_SESSION"],
		"_SERVER" => ["REQUEST_TIME_FLOAT"],
	]
);

The returned $allowed array contains only the whitelisted values, ready to be passed into overrideInternals().

What happens when a whitelisted key is missing?

If a whitelisted offset does not exist in the original array, the library still creates the offset with a value of null.

That means this is allowed:

$allowed = $protection->removeGlobals(
	[
		"_ENV" => $_ENV,
	],
	[
		"_ENV" => ["APP_ENV"],
	]
);

$protection->overrideInternals($allowed);

$_ENV["APP_ENV"] = "development";

The key did not have to exist before protection started, as long as it was explicitly whitelisted.

What is still blocked?

Only the named offsets remain available. Everything else still throws ProtectedGlobalException.

echo $_SERVER["REQUEST_TIME_FLOAT"]; // Allowed if whitelisted.
echo $_SERVER["HTTP_HOST"];          // Throws if not whitelisted.

Keep the whitelist small

The whitelist is most useful when it stays narrow and deliberate.

  • Prefer keeping whole superglobals protected.
  • Whitelist only the exact offsets a tool genuinely requires.
  • Favour passing data through objects, function arguments, or services instead of relying on globals.

That way the codebase still gains the main benefit of the library: making hidden global dependencies visible.


Next: Understanding the ProtectedGlobal object