PHP.INI settings Disable exec, shell_exec, system, popen and Other Functions To Improve Security

I run a small Apache based web-server for my personal use, and it is shared with friends and family. However, most script kiddie try to exploit php application such as WordPress using exec(), passthru(), shell_exec(), system() functions. How do I disable these functions to improve my php script security?

Tutorial details
Difficulty Easy (rss)
Root privileges Yes
Requirements LAMP
Time 5m
PHP has a lot of functions which can be used to crack your server if not used properly. You can set list of functions in php.ini using disable_functions directive. This directive allows you to disable certain functions for security reasons. It takes on a comma-delimited list of function names. disable_functions is not affected by Safe Mode.
PHP.INI settings Disable exec, shell_exec, system, popen and Other Functions To Improve Security

My sample php.ini

This directive must be set in php.ini file. For example, you cannot set this in httpd.conf file. This page shows how to edit the php.ini to disable certain function and restart the required services.

ADVERTISEMENTS

PHP.INI settings Disable exec, shell_exec, system, popen and Other Functions To Improve Security

Open a terminal application or login to your server over the ssh session using ssh command. Open php.ini file using a text editor such as vim command or nano command:
$ sudo vi /etc/php.ini
OR
$ sudo nano /etc/php.ini
Find disable_functions and set new list as follows:

# list of function to disable globally #
disable_functions =exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source

I also recommend to disable allow_url_include and allow_url_fopen for security reasons:

allow_url_fopen=Off
allow_url_include=Off

Save and close the file. Restart the httpd server by tying the following command:
# service httpd restart
OR if you are using Debian/Ubuntu Linux, run:
# service apache2 restart

A note about systemd based system

If you are using systemd + RHEL/CentOS/Fedora Linux based system, enter:
# systemctl httpd restart
If you are using systemd + Debian/Ubuntu Linux based system, enter:
# systemctl restart apache2

A note about PHP-fpm under a Debian/Ubuntu/CentOS Linux

Create a file named security.ini /etc/php/7.0/fpm/conf.d/ directory:
$ vi sudo /etc/php/7.0/fpm/conf.d/99-security.ini
Append the following settings:

# disable functions 
disable_functions=exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source

Save and close the file when using a vim text editor. Next you need to restart the php-fpm/php7.0-fpm/php5.0-fpm service service, run:
$ sudo systemctl restart php-fpm # <- CentOS/RHEL 7.x
$ sudo systemctl restart php7.0-fpm.service # <- Ubuntu/Debian

See also:
  • Linux: 25 PHP Security Best Practices For Sys Admins – A misconfigured server-side scripting language can create all sorts of problems. So, PHP should be used with caution. Here are twenty-five php security best practices for sysadmins for configuring PHP securely.
🐧 Get the latest tutorials on SysAdmin, Linux/Unix, Open Source/DevOps topics:
CategoryList of Unix and Linux commands
File Managementcat
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network Utilitiesdig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04

ADVERTISEMENTS
33 comments… add one
  • Davide Jul 30, 2008 @ 14:59

    This is not enought because you can always use “`” that will bypass these limitation.

    • Tibor Apr 8, 2016 @ 15:35

      That’s not true: When shell_exec() has been disabled, the backticks are unavailable as well.
      See http://php.net/manual/en/language.operators.execution.php:
      “Note: The backtick operator is disabled when safe mode is enabled or shell_exec() is disabled.”

      • Tibor Apr 8, 2016 @ 15:38

        Sorry, I overlooked the comment by “Experts” that was not filed as a reply to Davide.

  • Eric Lin Aug 3, 2008 @ 22:24

    I guess if you really need those functions, you can overwrite the configuration using ini_set function in your script to enable them for a particular site.

    • mrez.ir Jul 3, 2015 @ 12:03

      I can’t understand if they can be re-enabled in scripts why should we disable them? hackers may use ini_set() to enable them! Or is there any restrictions/limits for hackers while calling ini_set() that I don’t know?

  • Experts Nov 10, 2008 @ 12:21

    Davide you are wrong “`” using shell_exec function so if we disable shell_exec then “`” will be disabled too

  • Mir Mar 30, 2010 @ 13:03

    Why is “parse_ini_file” disabled?

  • cliffsupport Apr 26, 2010 @ 10:20

    You should make sure the user cannot override the setting using .htaccess or custom php.ini

  • Lekensteyn May 12, 2010 @ 10:55

    show_source is an alias of highlight_file.
    Why would you disable this function?
    You can read the contents of a file with readfile() or file_get_contents :/

  • mica Sep 19, 2010 @ 20:44

    readfile() and file_get_contents() functions are subject to the open_basedir restriction.
    Obviously you should set the open_basedir php setting to your docroot, so the scripts won’t be able to read files above docroot in your file system!

  • ubuntu lover Apr 14, 2011 @ 10:47

    if i create a custom php.ini file, it would overwrite disable_functions directive, so this is useless.
    how can you overcome that???

  • Daniel Alexandre May 14, 2011 @ 7:35

    “ubuntu lover”: Either you want to disable those functions or not. If you want you have to change php.ini: overwrite disable_functions and set a new list or modify the existing one. I’m not sure you think it makes it useless. Only the server admin can do that and he will only disable the functions he wants, editing that list.
    Also Eric says: “if you really need those functions, you can overwrite the configuration using ini_set function in your script to enable them for a particular site.” But again you can do that only on the server side.

  • kishan Dec 10, 2011 @ 5:42

    this functions easily bypassed with cgi telnet perl script!

    • anon Jan 28, 2012 @ 12:35

      So what’s the solution? To disable telnet?

      • poncio Mar 30, 2012 @ 7:29

        =S

      • lorenzop Oct 25, 2016 @ 8:31

        if telnet is enabled.. you need to re-assess your system security

  • xyz kr sin Apr 14, 2012 @ 11:20

    it didnot work for me

  • Michael Scherer Apr 27, 2012 @ 13:13

    Helo, sorry my english is not so good. My Question: How can I enable exec on Linux? Thanks for the Answers :-) Bye

  • Rick Jul 26, 2012 @ 13:23

    Here is the list i use. Most script dont use any of these functions anyway (except for chmod maybe, for file management script or something).

    exec, passthru, shell_exec, system, proc_open, posix_mkfifo, pg_lo_import, dbmopen, dbase_open, popen, chgrp, chown, chmod, symlink, pcntl_exec,
    apache_child_terminate, apache_setenv, define_syslog_variables, posix_getpwuid, posix_kill, posix_mkfifo, posix_setpgid, posix_setsid, posix_setuid,
    posix_setuid, posix_uname, proc_close, pclose, proc_nice, proc_terminate, shell_exec

  • tumi Aug 8, 2012 @ 5:55

    only disable those setting,it it enough ? how about the following too over ?

    disable_functions = show_source, system, shell_exec, passthru, exec, popen, proc_open, allow_url_fopen, phpinfo, gzinflate, fsockopen, pfsockopen
    
  • darius May 18, 2013 @ 23:35

    imo you should look limitations in wordpress not in php. It’s program not language unsafe.

  • John Jun 17, 2013 @ 8:10

    Best one I could found is this :

    #Protect your website from Hacking using this php.ini By Mauritania Attacker

    safe_mode = On
    disable_functions = "ln, cat, popen, pclose, posix_getpwuid, posix_getgrgid, posix_kill, parse_perms, system, dl, passthru, exec, shell_exec, popen, proc_close, proc_get_status, proc_nice, proc_open, escapeshellcmd, escapeshellarg, show_source, posix_mkfifo, mysql_list_dbs, get_current_user, getmyuid, pconnect, link, symlink, pcntl_exec, ini_alter, pfsockopen, leak, apache_child_terminate, posix_kill, posix_setpgid, posix_setsid, posix_setuid, proc_terminate, syslog, fpassthru, stream_select, socket_select, socket_create, socket_create_listen, socket_create_pair, socket_listen, socket_accept, socket_bind, socket_strerror, pcntl_fork, pcntl_signal, pcntl_waitpid, pcntl_wexitstatus, pcntl_wifexited, pcntl_wifsignaled, pcntl_wifstopped, pcntl_wstopsig, pcntl_wtermsig, openlog, apache_get_modules, apache_get_version, apache_getenv, apache_note, apache_setenv, virtual, chmod, file_upload, delete, deleted, edit, fwrite, cmd, rename, unlink, mkdir, mv, touch, cp, cd, pico"
    safe_mode_gid = On
    open_basedir = On
    register_globals = Off
    exec = Off
    shell_exec = Off
    allow_url_fopen = Off
    allow_url_include = Off
  • sachin karma Jul 10, 2013 @ 10:39

    Hello Experts,
    i have a problem i have installed mysql and lamp on my fedora linux .
    i have configured phpmyadmin also so that it can connect to the mysql socket.
    all works with http://localhost/ and http://localhost/phpmyadmin in the browser …
    but when i tried running my db.php file which contains following

    give me errors
    Warning: mysql_connect(): No such file or directory in /opt/lampp/htdocs/hellophp/index.php on line 2
    No such file or directory

    this works fine on my windows but not on linux although all configuration of lampp is fine..help

  • sachin karma Jul 10, 2013 @ 10:40

    here is my code :

    mysql_connect(“localhost:3306″,”root”,”sach”) or die(mysql_error());
    mysql_select_db(“sample”) or die(mysql_error());

  • sachin karma Jul 10, 2013 @ 10:41

    i have tried removing 3306 still not working
    same problem
    Warning: mysql_connect(): No such file or directory in /opt/lampp/htdocs/hellophp/index.php on line 2

  • Michael Dec 28, 2013 @ 19:42

    This article is laughable at best. Sure, the functions mentioned can be used to exploit security issues, but if your server is properly configured, you shouldn’t need to do so.

    exec, passthru, shell_exec, system, proc_open and popen are all dependent on server permissions. If your server is configured properly, the user accounts should not be able to do anything dangerous with these.

    curl_exec and curl_multi_exec are both quite useful. I don’t see how these can be dangerous.

    parse_ini_file and show_source are both completely harmless. I highly recommend you read up on what these do before you go blindly recommending people disable them.

    • Tibor Apr 8, 2016 @ 15:53

      Maybe these restrictions are useful on servers where different webspace users (i.e. actual people) “share” one UNIX user account (separate accounts only on the FTP server etc.). IIRC this is the case in typical Apache installations (all PHP scripts run as user “apache”, and there are no separate PHP interpreter processes being created which could get their user ID changed).
      So if PHP scripts were allowed full access, the FTP server’s restrictions would become useless. (But still then you need to disable CGI, otherwise one can upload and execute shell scripts…)

  • Tapan Bhanot Mar 5, 2014 @ 15:43

    I use this list:

    apache_child_terminate, apache_setenv, define_syslog_variables, escapeshellarg, escapeshellcmd, eval, exec, fp, fput, ftp_connect, ftp_exec, ftp_get, ftp_login, ftp_nb_fput, ftp_put, ftp_raw, ftp_rawlist, highlight_file, ini_alter, ini_get_all, ini_restore, inject_code, openlog, passthru, php_uname, phpAds_remoteInfo, phpAds_XmlRpc, phpAds_xmlrpcDecode, phpAds_xmlrpcEncode, popen, posix_getpwuid, posix_kill, posix_mkfifo, posix_setpgid, posix_setsid, posix_setuid, posix_setuid, posix_uname, proc_close, proc_get_status, proc_nice, proc_open, proc_terminate, shell_exec, show_source, syslog, system, xmlrpc_entity_decode, ini_set
    

    Works fine.

    Thanks.

    • Lenin Meza Dec 7, 2016 @ 16:58

      php_uname is used by Composer
      openlog is used by some modules in Drupal 8

  • linuxman1 Jan 15, 2015 @ 20:20

    Why not to use mod_security2 with some good rules to protect the web site from such attacks?

  • Tapan Bhanot Jan 16, 2015 @ 8:08

    Hi,

    Where to get good mod_secuirty2 rules ?

    Thanks.

  • Alex Feb 3, 2016 @ 9:14

    Those who advising to disable ‘eval’ should read PHP documentation and understand that language instead of blindly copy-paste “smart” advises and reporting without testing that it’s “works good” for them.

    Eval – is a language construct(same as ‘echo’) and CAN NOT be disabled without third party extension such as Suhosin

  • phptechie Aug 14, 2020 @ 7:37

    Excellent post! Thanks for the content.It saves my time. Thanks a lot.

Leave a Reply

Your email address will not be published.

Use HTML <pre>...</pre>, <code>...</code> and <kbd>...</kbd> for code samples.