If you have an installation of Nginx and PHP-FPM, PHP Powered-By headers are exposed by default. But you may need to hide PHP headers such X-Powered-By and X-CF-Powered-By to limit server information exposed to the public. This is one of the security mechanism.
X-Powered-By and X-CF-Powered-By PHP headers are disabled on FastCGI section of your Nginx configuration for a site. To use this guide, you should be using Nginx and PHP-FPM. Here are configuration examples.
For generic nginx configuration file.
############
# Pass all .php files onto a php-fpm or php-cgi server
############
location ~ \.php$ {
try_files $uri =404;
include /etc/nginx/fastcgi_params;
fastcgi_read_timeout 3600s;
fastcgi_buffer_size 128k;
fastcgi_connect_timeout 3s;
fastcgi_send_timeout 120s;
fastcgi_temp_file_write_size 256k;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
#fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
# Hide PHP headers
fastcgi_hide_header X-Powered-By;
fastcgi_hide_header X-CF-Powered-By;
}
If you have a PHP-FPM configuration in a separate file, it should be set like below.
$ cat /etc/nginx/nginxconfig.io/php_fastcgi.conf
# 404
try_files $fastcgi_script_name =404;
# default fastcgi_params
include fastcgi_params;
# fastcgi settings
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
fastcgi_buffers 8 16k;
fastcgi_buffer_size 32k;
# Hide PHP headers
fastcgi_hide_header X-Powered-By;
fastcgi_hide_header X-CF-Powered-By;
# fastcgi params
fastcgi_param DOCUMENT_ROOT $realpath_root;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param PHP_ADMIN_VALUE "open_basedir=$base/:/usr/lib/php/:/tmp/";
The fastcgi_hide_header directive sets additional fields that will not be passed. If, on the contrary, the passing of fields needs to be permitted, the fastcgi_pass_header directive can be used.
Validate your Nginx configurations.
$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Restart Nginx for the changes to take effect.
sudo systemctl restart nginx php-fpm
Confirm Settings
Here is the output of my website curl before disabling the headers.
$ curl -IL https://geeksforgeeks.org
HTTP/2 200
date: Sat, 20 Apr 2019 20:44:38 GMT
content-type: text/html; charset=UTF-8
vary: Accept-Encoding
x-powered-by: PHP/7.3.1
x-cf-powered-by: WP Rocket 3.2.4
link: https://geeksforgeeks.org/wp-json/; rel="https://api.w.org/"
x-frame-options: SAMEORIGIN
x-xss-protection: 1; mode=block
x-content-type-options: nosniff
referrer-policy: no-referrer-when-downgrade
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
server: cloudflare
cf-ray: 4ca9f5130d66cb75-MBA
And after making the change and restarting Nginx.
$ curl -IL https://geeksforgeeks.org
HTTP/2 200
date: Sat, 20 Apr 2019 20:44:38 GMT
content-type: text/html; charset=UTF-8
vary: Accept-Encoding
link: https://geeksforgeeks.org/wp-json/; rel="https://api.w.org/"
x-frame-options: SAMEORIGIN
x-xss-protection: 1; mode=block
x-content-type-options: nosniff
referrer-policy: no-referrer-when-downgrade
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
server: cloudflare
cf-ray: 4ca9f5130d66cb75-MBA
You can confirm there are no x-powered-by
and x-cf-powered-by
directives in the output. The same can be checked from the browser under Inspect > Network > Headers > Response Headers.
Also read:
- How To Enable GZIP & Brotli Compression for Nginx on Linux
- Resolve “413 Request Entity Too Large Error” on Nginx / Apache
- Configure JFrog Artifactory behind Nginx reverse proxy and Let’s Encrypt SSL
- Configure Jenkins behind Nginx reverse proxy and Let’s Encrypt SSL
- Configure Jenkins behind Nginx reverse proxy and Let’s Encrypt SSL