50

I know in PHP, it sends the X-Powered-By header to have the PHP version.

I also know by appending some checksums, you can get access to PHP's credits, and some random images (more info here).

I also know in php.ini you can turn expose_php = off.

But here is something I have done on a few sites, and that is use

header('X-Powered-By: Alex');

When I view the headers, I can see that it is now 'Alex' instead of the PHP version. My question is, will this send the previous PHP header first (before it reaches my header(), and is it detectable by any sniffer program? Or are headers 'collected' by PHP, before being sent back to the browser?

By the way, this is not for security by obscurity, just curious how headers work in PHP.

hakre
  • 193,403
  • 52
  • 435
  • 836
alex
  • 479,566
  • 201
  • 878
  • 984

8 Answers8

39

You can set expose_php = Off in your php.ini if you don't want it to send X-Powered-By header.

PHP first compiles everything (including which headers have which values ) and then start the output, not vice-versa.

PHP is also detectable with its own easter eggs, you can read about this topic here : PHP Easter Eggs

LWC
  • 1,084
  • 1
  • 10
  • 28
Kemo
  • 6,942
  • 3
  • 32
  • 39
29

See Apache Tips & Tricks: Hide PHP version (X-Powered-By)

Ups… As we can see PHP adds its own banner:

X-Powered-By: PHP/5.1.2-1+b1…

Let’s see how we can disable it. In order to prevent PHP from exposing the fact that it is installed on the server, by adding its signature to the web server header we need to locate in php.ini the variable expose_php and turn it off.

By default expose_php is set to On.

In your php.ini (based on your Linux distribution this can be found in various places, like /etc/php.ini, /etc/php5/apache2/php.ini, etc.) locate the line containing expose_php On and set it to Off:

expose_php = Off

After making this change PHP will no longer add it’s signature to the web server header. Doing this, will not make your server more secure… it will just prevent remote hosts to easily see that you have PHP installed on the system and what version you are running.

cletus
  • 616,129
  • 168
  • 910
  • 942
  • 3
    But this only advices to set 'expose_php = Off' in php.ini what alex already mentioned in his post. – Ludwig Aug 26 '14 at 17:09
18

In PHP, headers aren't sent until PHP encounters its first output statement.

This includes anything before the first <?php.

This is also why setcookie sends throws a warning if you try to use it after something has been output:

Warning: Cannot modify header information - headers already sent by (output started at /path/to/php/file.php:100) in /path/to/php/file.php on line 150

Note that none of this applies if output buffering is in use, as the output will not be sent until the appropriate output buffering command is run.

Tyilo
  • 28,998
  • 40
  • 113
  • 198
Powerlord
  • 87,612
  • 17
  • 125
  • 175
4

To hide X-Powered-By: PHP/7.x.x , if you are using Share Hosting then add the following code in .htaccess file

Header always unset X-Powered-By
Header unset X-Powered-By

Then reload the browser or clear the cache using the LiteSpeed ​​Cache plugin: https://en.wordpress.org/plugins/litespeed-cache/

Trinh Hieu
  • 379
  • 3
  • 6
3

Headers are "collected" by PHP before being sent back to the browser, so that you can override things like the status header. The way to test it is go to a command prompt, and type:

telnet www.yoursite.com 80
GET /index.php HTTP/1.1
[ENTER]
[ENTER]

And you'll see the headers that are sent in the response (replace /index.php with the URL of your PHP page after the domain.)

Andy Shellam
  • 15,403
  • 1
  • 27
  • 41
3

To get rid of the X-Powered-By header without having access to php.ini, simply add an empty header.

<?php header('X-Powered-By:'); ?>

This overwrites the default X-Powered-By header with an empty value an though most clients and applications act like this header was not sent at all.

As noticed before, this must be inserted into the code before any output is sent.

And to answer your question:

Only your X-Powered-By header will be sent because it gets replaced by your header with the same name. So it can't be detected by a 'sniffer'.

Ludwig
  • 3,580
  • 2
  • 20
  • 24
2

My question is, will this send the previous PHP header first (before it reaches my header(), and is it detectable by any sniffer program? Or are headers 'collected' by PHP, before being sent back to the browser?

No, it does not send the previous PHP header first. Headers are either sent or not sent (in complete, as one batch) in PHP. By default your headerDocs call replaces a previous header with the same name (unless you specify something different with the second parameter).

Note: If PHP would not collect the headers, it would not be able to replace one.

As it does not sent it earlier, it is not detectable with a sniffer program.

So yes, headers are collected by PHP and are send the moment "the real" output starts (HTTP response body).

See as well headers_sentDocs.

hakre
  • 193,403
  • 52
  • 435
  • 836
0

PHP has a built-in function to remove headers: header_remove().

To remove the X-Powered-By header, you can use:

<?php

header_remove(
    name: 'X-Powered-By'
);

As you can see, you only have to pass the header name as a string as parameter, and you are done.

Note that name parameter is parsed not case-sensitive, so you are fine calling it with x-powered-by as well.


Since PHP 8.0.0 when calling the function without the name parameter, all previously set headers will be unset.

David Wolf
  • 1,400
  • 1
  • 9
  • 18