Technologies
PHP
PHP is recognisable from outside through two defaults: the `X-Powered-By: PHP/x.y.z` header, sent when the `expose_php` setting is on, and the `PHPSESSID` session cookie name. The header publishes the exact PHP version, which makes it the most precise version disclosure an audit commonly finds. PHP's built-in defaults also leave the session cookie without the Secure and HttpOnly flags until the configuration sets them.
How the engine recognises it
`X-Powered-By` beginning with `PHP` — weight 90.
A `PHPSESSID` cookie — weight 75.
Either is enough on its own, and each is a PHP default rather than a choice the application made.
PHP is reported as a runtime. Laravel, Symfony, WordPress and other PHP software are separate rules and are never inferred from PHP alone.
expose_php and the published version
PHP's documentation describes `expose_php` as exposing to the world that PHP is installed on the server, including the PHP version in the HTTP header — its example is `X-Powered-By: PHP/5.3.7`.
Its built-in default is on, and it can only be changed in `php.ini`, not from application code.
When the header is present, the version it names is listed exactly as published, and nothing is inferred beyond it.
Comparing that version with PHP's supported-versions table tells you whether the branch still receives security fixes — which matters more than hiding the header.
Session cookie defaults
`session.name` defaults to `PHPSESSID`, which is why the cookie name identifies the runtime.
`session.cookie_secure` defaults to off, so the session cookie is also sent over plain HTTP unless configured.
`session.cookie_httponly` defaults to off, so script on the page can read it.
`session.cookie_samesite` has no default value, and `session.use_strict_mode` defaults to off.
Frameworks usually set these themselves; a bare `PHPSESSID` without flags is a sign nobody did.
The `session.cookie_samesite` setting exists only since PHP 7.3, so older runtimes cannot set the attribute through configuration at all.
What recognition does and does not prove
It proves a PHP runtime produced the response or set the cookie.
It does not identify the web server in front of PHP, which is reported from its own header.
An absent header proves nothing: `expose_php` may simply be off, which is common.
A published version is an inventory fact; whether it is still supported is the part to act on.
Which checks apply
`technology.inventory` and `technology.versions` list PHP and the exact version published.
`security.server_disclosure` reports `X-Powered-By` as a version disclosure.
`cookies.secure`, `cookies.httponly` and `cookies.samesite` report the session cookie's flags as actually set.
On WordPress sites, `wordpress.php` reports the PHP version against WordPress's requirements.
Session fixation and strict mode
`session.use_strict_mode` defaults to off. The documentation explains that with strict mode on, PHP does not accept an uninitialised session ID sent by the browser and issues a new one instead.
It states that strict mode protects applications from session fixation via session adoption.
`session.cookie_lifetime` defaults to `0`, so the session cookie lasts until the browser closes, and `session.cookie_path` defaults to `/`.
None of these settings is visible from outside except through the cookie the server sets, which is what the audit reads.
`session.use_cookies` and `session.use_only_cookies` both default to on, and the manual notes that disabling `use_only_cookies` is deprecated as of PHP 8.4.
Keeping session IDs in cookies only is what stops them appearing in URLs, where they would leak through logs and referrers.
Frequently asked questions
- How do I remove X-Powered-By: PHP?
- Set `expose_php = Off` in php.ini. The setting cannot be changed from application code, which is why the header often survives framework-level hardening.
- Is a visible PHP version a vulnerability?
- Not on its own. It matters when the version is no longer supported; check it against PHP's supported-versions table.
- Why is my PHPSESSID cookie missing the Secure flag?
- Because `session.cookie_secure` is off by default. Turn it on for a site served over HTTPS, along with `session.cookie_httponly`.
Sources
Related
VeriFixScan crawls a site and applies its checks to every page it reaches, keeping the evidence behind each finding. Scanning one website is free.
Scan a website