10 Steps for Securing a PHP Application
This guide presents ten concrete PHP configuration tweaks—including longer session IDs, restricted session storage, hardened cookies, open_basedir limits, and disabled risky functions—to substantially improve the security of a PHP app, with ready‑to‑use Docker‑compatible commands.
Hello PHP developers. In this article I provide concrete steps to improve the security of PHP applications by focusing on PHP configuration itself, without covering SQL injection, HTTPS, or other non‑PHP topics.
I illustrate the changes using bash lines from my docker-entrypoint.sh script, but the same adjustments apply to non‑Docker environments.
Sessions
Use a longer Session ID length
Increasing the session ID length makes brute‑force or side‑channel guessing harder; valid lengths range from 22 to 256 characters, with the default of 32.
<code>sed -i -e "s/session.sid_length = 26/session.sid_length = 42/" /etc/php7/php.ini</code>Use a custom session save path with restricted permissions
Only nginx/php need access to sessions, so place them in a dedicated folder with limited rights.
<code>sed -i -e "s:;session.save_path = \"/tmp\":session.save_path = \"/sessions\":" /etc/php7/php.ini
mkdir -p /sessions
chown nginx:nginx /sessions
chmod 700 /sessions</code>If you use Redis for sessions, this step can be skipped.
Secure session cookies
Enable session.cookie_httponly to block JavaScript access, and set session.cookie_secure to prevent transmission over plain HTTP. Also enable session.cookie_samesite (available in recent PHP/browser versions) to mitigate cross‑site attacks.
<code>sed -i -e "s/session.cookie_httponly.*/session.cookie_httponly = true/" /etc/php7/php.ini
sed -i -e "s/;session.cookie_secure.*/session.cookie_secure = true/" /etc/php7/php.ini</code>Enable strict mode so that an attacker‑initialized session ID cannot be used.
<code>sed -i -e "s/session.use_strict_mode.*/session.use_strict_mode = true/" /etc/php7/php.ini</code>Set session.cookie_lifetime to 0 so sessions expire when the browser closes.
<code>sed -i -e "s/session.cookie_lifetime.*/session.cookie_lifetime = 0/" /etc/php7/php.ini</code>Open_basedir
The open_basedir directive limits the file system paths PHP can access.
<code>sed -i -e "s#;open_basedir =#open_basedir = /elabftw/:/tmp/:/usr/bin/unzip#" /etc/php7/php.ini</code>Here /elabftw holds the source PHP files; /tmp is included for reasons specific to the environment.
Disable risky functions
Disabling functions such as shell_exec can prevent uploaded web shells from executing.
<code>sed -i -e "s/disable_functions =/disable_functions = php_uname, getmyuid, getmypid, passthru, leak, listen, diskfreespace, tmpfile, link, ignore_user_abort, shell_exec, dl, system, highlight_file, source, show_source, fpaththru, virtual, posix_ctermid, posix_getcwd, posix_getegid, posix_geteuid, posix_getgid, posix_getgrgid, posix_getgrnam, posix_getgroups, posix_getlogin, posix_getpgid, posix_getpgrp, posix_getpid, posix_getppid, posix_getsid, posix_getuid, posix_isatty, posix_kill, posix_mkfifo, posix_setegid, posix_seteuid, posix_setgid, posix_setpgid, posix_setsid, posix_setuid, posix_times, posix_ttyname, posix_uname, phpinfo/" /etc/php7/php.ini</code>Disable allow_url_fopen
This option is dangerous; turn it off.
<code>sed -i -e "s/allow_url_fopen = On/allow_url_fopen = Off/" /etc/php7/php.ini</code>Disable cgi.fix_pathinfo
Prevent non‑PHP files from being executed as PHP.
<code>sed -i -e "s/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/g" /etc/php7/php.ini</code>Hide PHP version
Turn off exposure of the PHP version.
<code>sed -i -e "s/expose_php = On/expose_php = Off/g" /etc/php7/php.ini</code>That’s it. I hope you find these configuration tweaks useful and improve your PHP setup. If I missed anything important, please let me know in the comments.
php中文网 Courses
php中文网's platform for the latest courses and technical articles, helping PHP learners advance quickly.
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.