25 Essential PHP Security Best Practices for Hardened Web Servers
This guide presents 25 practical PHP security best practices, covering configuration files, module management, error handling, file uploads, remote code execution, SQL safety, resource limits, user permissions, SELinux, firewall rules, and additional tools, to help administrators harden PHP deployments on Linux servers.
PHP is a widely used open‑source server‑side scripting language, but misconfiguration can expose many vulnerabilities. The following 25 best practices provide a comprehensive checklist for securing PHP on Linux servers, assuming root access and a typical Apache (or Lighttpd/Nginx) environment.
Environment Overview
DocumentRoot: /var/www/html Web server: Apache (alternatives Lighttpd, Nginx)
PHP config file: /etc/php.ini Additional module configs: /etc/php.d/ Custom security config: /etc/php.d/security.ini OS: RHEL/CentOS/Fedora (commands also apply to Debian/Ubuntu, OpenBSD, FreeBSD, HP‑UX, etc.)
Best Practice 1 – Know Your Threats
Common PHP attack vectors include XSS, SQL injection, unsafe file uploads, remote file inclusion, use of eval(), and CSRF. Mitigation requires input validation, disabling dangerous functions, and configuring the web server to limit exposure.
Best Practice 2 – Audit Built‑in Modules
List compiled modules with php -m. Remove unnecessary modules to reduce attack surface, e.g.:
# rm /etc/php.d/sqlite3.ini
# mv /etc/php.d/sqlite3.ini /etc/php.d/sqlite3.disableRecompile PHP with only required extensions (GD, MySQL, FastCGI) using a configure command similar to:
./configure --with-libdir=lib64 --with-gd --with-mysql --prefix=/usr \
--exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin \
--sysconfdir=/etc --datadir=/usr/share --includedir=/usr/include \
--enable-fastcgi --enable-force-cgi-redirectBest Practice 3 – Hide PHP Version Information
Disable expose_php in /etc/php.d/security.ini: expose_php=Off Also set ServerTokens and ServerSignature in the Apache configuration to hide server details.
Best Practice 4 – Minimize Loaded Extensions
Comment out or rename unneeded .ini files in /etc/php.d/. Example to disable the GD extension:
# cd /etc/php.d/
# mv gd.{ini,disable}
# /sbin/service httpd restartTo re‑enable, reverse the rename.
Best Practice 5 – Log All PHP Errors
Turn off on‑screen error display and log errors to a file:
display_errors=Off
log_errors=On
error_log=/var/log/httpd/php_scripts_error.logBest Practice 6 – Control File Uploads
Disable uploads globally: file_uploads=Off If uploads are needed, enable them and set a size limit:
file_uploads=On
upload_max_filesize=1MBest Practice 7 – Disable Remote Code Execution
Turn off allow_url_fopen and allow_url_include:
allow_url_fopen=Off
allow_url_include=OffBest Practice 8 – Enable SQL Safe Mode
Activate sql.safe_mode and disable magic_quotes_gpc:
sql.safe_mode=On
magic_quotes_gpc=OffBest Practice 9 – Limit POST Request Size
Restrict maximum POST data to 1 KB (adjust as needed): post_max_size=1K Also limit HTTP methods in Apache:
<Directory /var/www/html>
<LimitExcept GET POST>
Order allow,deny
</LimitExcept>
</Directory>Best Practice 10 – Resource Controls
Set execution time, input time, and memory limits:
max_execution_time=30
max_input_time=30
memory_limit=40MBest Practice 11 – Install Suhosin
Suhosin provides advanced hardening for PHP core and extensions. Follow the project’s installation guide for Linux.
Best Practice 12 – Disable Dangerous Functions
Use disable_functions to block high‑risk calls:
disable_functions=exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_sourceBest Practice 13 – Enforce cgi.force_redirect
Enable cgi.force_redirect to prevent direct CGI execution:
cgi.force_redirect=OnBest Practice 14 – Run PHP as a Non‑Root User
Configure Apache’s suEXEC or mod_suPHP so PHP runs under a low‑privilege account (e.g., phpcgi).
Best Practice 15 – Restrict Filesystem Access
Set open_basedir to limit PHP to specific directories:
open_basedir="/var/www/html/"Best Practice 16 – Secure Session Storage
Define a dedicated session directory with proper permissions:
session.save_path="/var/lib/php/session"
upload_tmp_dir="/var/lib/php/session"Best Practice 17 – Keep Software Updated
Regularly apply updates via package managers:
# yum update
# apt-get update && apt-get upgradeBest Practice 18 – Harden File Permissions
Run Apache as a non‑root user and set read‑only permissions for web files:
# chown -R apache:apache /var/www/html/
# chmod -R 0444 /var/www/html/
# find /var/www/html/ -type d -exec chmod 0445 {} \;Best Practice 19 – Make Configuration Files Immutable
Use chattr +i to protect critical config files:
# chattr +i /etc/php.ini
# chattr +i /etc/php.d/*
# chattr +i /etc/httpd/conf/httpd.confBest Practice 20 – Enable SELinux
Leverage SELinux policies to restrict Apache and PHP actions. Example to view HTTPD booleans: # getsebool -a | grep httpd Disable CGI support if not needed:
# setsebool -P httpd_enable_cgi offBest Practice 21 – Deploy ModSecurity
Install ModSecurity and add simple filters:
SecFilter /etc/
SecFilter "delete[[:space:]]+from"
SecFilter "select.+from"Best Practice 22 – Use chroot Jails
Run Apache/PHP inside a chroot or container (FreeBSD jail, XEN, KVM, OpenVZ) to isolate the filesystem.
Best Practice 23 – Restrict Outbound Connections
Configure iptables to limit outbound traffic for the Apache user:
# /sbin/iptables -A OUTPUT -o eth0 -m owner --uid-owner apache -j REJECTBest Practice 24 – Log Monitoring and Auditing
Continuously tail Apache and PHP error logs and use grep or egrep to spot suspicious entries. Enable auditd for SELinux and file change auditing.
Best Practice 25 – Service Segmentation
Distribute services across multiple servers or VMs (static assets on Lighttpd/Nginx, dynamic PHP on Apache, MySQL on a dedicated host, Memcached for caching, and an Nginx load balancer in front).
Additional Tools
Consider PHPIDS for intrusion detection and PhpSecInfo for automated security reporting.
Disclaimer: The content is compiled from public sources for reference only; original copyrights belong to the authors.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Art of Distributed System Architecture Design
Introductions to large-scale distributed system architectures; insights and knowledge sharing on large-scale internet system architecture; front-end web architecture overviews; practical tips and experiences with PHP, JavaScript, Erlang, C/C++ and other languages in large-scale internet system development.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
