Hiding PHP

Yo Yogesh.M Updated 17 Oct 2026
5 min read ·Lesson 83 of 109
In this post

Hiding PHP What Does "Hiding PHP" Mean? In simple terms: By default, a PHP website announces itself in several ways: response headers say X-Powered-By: PHP/8.4.3 , URLs end in .php , the session cooki

Hiding PHP

What Does "Hiding PHP" Mean?

In simple terms: By default, a PHP website announces itself in several ways: response headers say X-Powered-By: PHP/8.4.3, URLs end in .php, the session cookie is called PHPSESSID, and error pages show PHP file paths. Hiding PHP removes these clues, so visitors — and automated attack tools — learn less about your technology stack and exact versions.

Technically: "Hiding PHP" is a set of configuration and design choices that reduce information disclosure: disabling version headers (expose_php, server tokens), using a front controller with clean URLs, renaming default cookies, disabling error display, and removing default or diagnostic files. It is security through obscurity — useful as an extra layer that slows down automated scanners, but never a replacement for real security measures and keeping software updated.


Removing Version Headers

The X-Powered-By Header

With default settings, every PHP response includes a header like this:

HTTP/1.1 200 OK
Server: nginx/1.24.0
X-Powered-By: PHP/8.4.3
Content-Type: text/html; charset=UTF-8

Attackers and bots scan for specific versions with known vulnerabilities. Disable the header in php.ini:

expose_php = Off

expose_php can only be set in php.ini (it is a system-level setting). If you cannot change php.ini, remove the header in your application before any output:

<?php
header_remove('X-Powered-By');

Web Server Version Information

The web server reveals its own version too. Hide it in the server configuration:

# Nginx (http block)
server_tokens off;
# Apache
ServerTokens Prod
ServerSignature Off

After the Changes

HTTP/1.1 200 OK
Server: nginx
Content-Type: text/html; charset=UTF-8

The response no longer states which PHP or server version is running.


Clean URLs With a Front Controller

URLs like /products.php?id=7 reveal the language immediately. Modern PHP applications route all requests through a single entry point — the front controller (public/index.php) — and use clean URLs such as /products/7.

Web Server Configuration

# Nginx: send everything that is not an existing file to index.php
location / {
    try_files $uri /index.php$is_args$args;
}

location = /index.php {
    fastcgi_pass unix:/run/php/php8.4-fpm.sock;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root/index.php;
}

# Do not execute any other .php file
location ~ \.php$ {
    return 404;
}
# Apache (.htaccess in public/)
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]

A Minimal Router

<?php
// public/index.php
function route(string $requestUri): string
{
    $path = parse_url($requestUri, PHP_URL_PATH) ?: '/';
    $path = $path === '/' ? '/' : rtrim($path, '/');

    $routes = [
        '/' => 'home',
        '/courses' => 'courses',
        '/contact' => 'contact',
    ];

    return $routes[$path] ?? 'not-found';
}

foreach (['/', '/courses', '/courses/', '/contact?ref=footer', '/admin.php'] as $uri) {
    echo str_pad($uri, 20) . '→ ' . route($uri) . "\n";
}

// In the real front controller:
// $page = route($_SERVER['REQUEST_URI'] ?? '/');
// if ($page === 'not-found') { http_response_code(404); }
// require __DIR__ . "/../src/pages/$page.php";

Output

/                   → home
/courses            → courses
/courses/           → courses
/contact?ref=footer → contact
/admin.php          → not-found

How It Works

  1. The web server forwards every request that is not a real static file (CSS, images) to index.php.
  2. The router looks at the path only (the query string is ignored for routing) and normalizes a trailing slash.
  3. Each path maps to a page name from a fixed list; unknown paths — including attempts to call .php files — result in "not found".
  4. Page files are loaded from src/pages/, which lies outside the document root and cannot be requested directly.

Besides hiding the technology, a front controller gives a single place for bootstrapping, security headers, CSRF checks, and error handling. Frameworks such as Laravel and Symfony are built this way.


Other Telltale Signs

ClueHow to Hide It
Session cookie named PHPSESSIDSet session.name to a neutral name such as __Host-SID (see Session Security)
PHP error messages with file pathsdisplay_errors = Off (see Error Reporting in Production)
Default and diagnostic files (phpinfo.php, test.php, info.php)Never deploy them
composer.json, composer.lock, .env, vendor/ reachable by URLKeep only public/ in the document root
Framework-specific paths and cookies (laravel_session, /wp-admin)Rename where the framework allows it; keep the software updated regardless
Default server error pagesReplace with custom, neutral error pages

Some guides suggest mapping other extensions (.html, .asp) to PHP to confuse attackers. This adds complexity and can cause security problems (for example, uploaded .html files being executed); clean URLs achieve the same goal properly.


Keeping Expectations Realistic

Hiding PHP does not make a vulnerable application safe:

  • Automated attacks often simply try exploits for many technologies, without checking versions first.
  • Response timing, HTML structure, cookies, and framework behavior can still reveal the stack.
  • The real protection is current software, secure code, and secure configuration.

Think of hiding PHP as removing labels from a locked door: it costs little and reduces noise from scanners, but the lock is what matters.


Common Mistakes

Relying on Obscurity Instead of Updates

Effect: Old, vulnerable versions remain exploitable regardless of hidden headers.

Fix: Keep PHP, extensions, the web server, and dependencies updated.

Removing Headers but Leaving Error Display On

Effect: Error pages still reveal paths and versions.

Fix: Disable display_errors in production.

Executing Arbitrary .php Files in the Document Root

Effect: Forgotten scripts (old tools, test files) remain reachable.

Fix: Allow PHP execution only for the front controller.

Leaving phpinfo() Files on Servers

Effect: Complete configuration and environment disclosure.

Fix: Delete them; use protected admin tools or the CLI instead.


Best Practices

  • Set expose_php = Off and hide web server version tokens.
  • Route all requests through a front controller with clean URLs.
  • Execute only the front controller; keep application code outside the document root.
  • Rename default cookies, disable error display, and remove diagnostic files.
  • Treat hiding as an extra layer — keep everything updated and securely coded.

Official reference: https://www.php.net/manual/en/security.hiding.php

0 Comments

Reviewed before they appear

No comments yet.

PHP
PHP Home PHP Switch PHP Match Alternative Syntax PHP Loops While Loop Do While Loop For Loop Foreach Loop Nested Loops Break Statement PHP Home PHP Intro PHP Install PHP Built-in Web Server PHP Syntax PHP Tags PHP and HTML PHP Comments PHP Multiline Comments PHP Variables Variables Scope PHP Casting Logical Operators Null Coalescing Operator Spaceship Operator Operator Precedence Continue Statement Modify Strings PHP If...Else...Elseif PHP If Modify Strings PHP If Operators PHP Functions Concatenate Strings PHP If...Else Slicing Strings User-defined Functions Slicing Strings PHP Shorthand if Escape Characters Default Argument Values PHP Nested if Pass by Reference String Interpolation Named Arguments PHP File Upload Variadic Functions Return Values Search in Strings Multibyte Strings Type Declarations in Functions PHP Numbers PHP Math PHP Floats PHP Random Numbers PHP Constants PHP Properties PHP Methods PHP Constructor Constructor Property Promotion PHP Cookies PHP Destructor PHP Access Modifiers Readonly Properties PHP Sessions PHP Inheritance Method Overriding PHP Filters The final Keyword CSRF Protection PHP Filters Advanced Session Security Secure Cookies PHP Magic Constants File Upload Security PHP Callback Functions PHP Operators Filesystem Security PHP JSON Arithmetic Operators Error Reporting in Production Hiding PHP Assignment Operators PHP Configuration (php.ini) Comparison Operators PHP Command Line (CLI) PHP Exceptions Increment / Decrement Operators Migrating to PHP 8 PHP Form Validation PHP Form Required PHP Form URL/E-mail Error Handling Form Input Sanitizing Escaping Output (htmlspecialchars) Custom Error Handler Checkbox, Radio and Select Inputs Sticky Forms PHP Form Complete PHP Date and Time Date Formatting Error Logging HTTP Headers and Redirects Output Buffering Sending Email PHP cURL Consuming REST APIs PHP Generators
Ask about this post
AI Ask about this post

Ask questions about Hiding PHP and get answers drawn from it.

Signed-in readers only.