Skip to content

VNX-PHP-008: PHP phpinfo exposure

Detect calls to phpinfo() in production PHP code, which disclose the PHP build, configuration, file paths, environment variables and request headers.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-PHP-008
Severity Medium
SARIF level warning
Kind sast
Languages PHP
CWE CWE-200
CAPEC CAPEC-54
ATT&CK T1592
CWSS vector CWSS:1.0/TI:M/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:M/DI:H/EX:M/EC:N/P:C
Tags information-disclosure reconnaissance php
Source internal/sast/rules/vnx-php-008.rego

Overview

This rule flags calls to phpinfo() in production PHP code (tests, CLI-guarded and debug-guarded calls excepted). phpinfo() outputs a comprehensive HTML page summarising the PHP runtime environment. While indispensable during local development, any reachable phpinfo() output in a production environment hands an attacker a detailed reconnaissance report about your server without requiring any vulnerability to exploit. This maps to CWE-200: Exposure of Sensitive Information to an Unauthorized Actor.

Why This Matters

The phpinfo() output page reveals an unusually dense set of reconnaissance data in a single request. Specifically, an attacker learns:

  • PHP version and exact build date, used to identify known CVEs for that specific minor/patch version.
  • Loaded extensions and their versions, reveals which attack surfaces are active (gd, curl, xml, soap, zip, pdo_*).
  • php.ini directives and their current values, shows whether dangerous settings like allow_url_include, allow_url_fopen, disable_functions, open_basedir, and display_errors are enabled or disabled.
  • Environment variables, includes PATH, SERVER_ADDR, DOCUMENT_ROOT, and any variables set in the server environment, which often include secrets injected via deployment pipelines.
  • $_SERVER and $_ENV contents, may expose database DSNs, API keys, cloud credentials, or internal hostnames depending on how the application is deployed.
  • Loaded configuration files, the exact paths to php.ini and additional .ini files loaded by the runtime.
  • Apache/Nginx module information, reveals the web server version and configuration.

With this information an attacker can precisely target exploit payloads to the exact versions running on your server, identify which security controls are missing, and find internal hostnames or credentials exposed through environment variables.

What Gets Flagged

A call to the phpinfo() function, with any argument, in code that is not a test or fixture.

// FLAGGED
phpinfo();
<?php phpinfo(INFO_GENERAL | INFO_MODULES); ?>
\phpinfo( INFO_ENVIRONMENT );

Not flagged: a call guarded within the five lines above by a CLI check (php_sapi_name() === "cli"), a loopback-client check, or a debug/local condition (APP_DEBUG, WP_DEBUG, app()->isLocal()); a call after an early bail such as if (PHP_SAPI !== "cli") { exit(1); }; methods named phpinfo; "phpinfo" as a string value, menu label or text inside a heredoc; test code; comments. A PHP_SAPI !== "cli" condition that wraps the call itself is still flagged.

Remediation

  1. Delete any standalone phpinfo() files from the codebase and web root. Files commonly named info.php, phpinfo.php, test.php, or i.php should be removed entirely. Check the web root (public_html, htdocs, public/, www/) and any directories served as static assets.

  2. Remove phpinfo() calls from application code. Use your IDE’s global search for phpinfo across the entire project. Remove every occurrence.

# Find all phpinfo() calls in the project
grep -r "phpinfo" /path/to/project --include="*.php"
  1. Use structured environment inspection instead of phpinfo() in legitimate diagnostic tools. If you need to inspect the PHP configuration programmatically, use ini_get(), phpversion(), get_loaded_extensions(), and getenv() to retrieve only the specific values you need, and ensure those endpoints are protected by authentication and only accessible to administrators:
// SAFE: minimal, authenticated diagnostic endpoint
session_start();
if (!isset($_SESSION['admin']) || $_SESSION['admin'] !== true) {
    http_response_code(403);
    exit;
}

header('Content-Type: application/json');
echo json_encode([
    'php_version'       => PHP_VERSION,
    'loaded_extensions' => get_loaded_extensions(),
    'memory_limit'      => ini_get('memory_limit'),
]);
  1. Disable phpinfo() via disable_functions in php.ini on production servers. Even if a call is accidentally reintroduced, the function will be a no-op:
; php.ini, production configuration
disable_functions = phpinfo,exec,passthru,shell_exec,system,proc_open,popen
  1. Set display_errors = Off and expose_php = Off in php.ini for all production environments. expose_php = Off removes the PHP version from HTTP response headers, eliminating another common fingerprinting vector.

References

Suppressing this rule

Put a nosec comment on the line, or on line 1 to cover the whole file. Use the comment marker of the file’s language (#, //, -- or ;):

# nosec vnx-php-008
// nosec vnx-php-008

Or record an ignore rule: vulnetix ignore add --rule vnx-php-008 --reason "...". See Suppressing findings.

Edit this pageSources: cli/internal/sast/rules/vnx-php-008.rego, cli/internal/sast/docs/vnx-php-008.md
esc
↑ ↓ move↵ openSearches in your browser. A key like autonomy.max or a code like threshold_required jumps straight to it.