If you are running php based web application it is very important to look at the following areas to secure the webserver:
- XSS: Cross-site scripting is a vulnerability in php web applications
- SQL Injection: It is a vulnerability in the database layer of an php application.
- File uploads: If attacker upload malicious file then he can basically gain the control of the server.
- Remote File Execution: An attacker can open files from remote server and execute any PHP code.
- eval(): A function that allows string to run as php code.
- CSRF: This attack forces an end user to execute unwanted actions on a web application in which he/she is currently authenticated.
Once you know kind of problems you are dealing with then you can tune your php configuration to secure your web app. First check what modules are installed by default when php was installed.
Command to list php installed module
Following command list all the installed modules in php:
php -m
Make sure you use necessary modules that you need for your web app. Remove unwanted modules or disable them.
Let's check the example about how you can remove the unwanted module:
# find the location where modules are stored # use this location in following commands php -i | grep ".ini files" # remove sqlite3 module mv /etc/php.d/sqlite3.ini /etc/php.d/sqlite3.disable # or remove it completly rm /etc/php.d/sqlite3.ini # other methods to turn on/off mv sqlite3.{ini,disable} mv sqlite3.{disable,ini}
Restrict PHP Information Leakage
To disable information related to installed php you need to disable the following configuration in your php.ini file:
# Find the location of your php.ini php -i | grep "php.ini" # search following variable # and turn this setting off expose_php=Off
Error logging
Make sure you do not log all the errors on the browser rather log them in a specific file to view via command line:
# Find the location of your php.ini php -i | grep "php.ini" # Open php.ini file from above location # Turn of Display error settings display_errors=Off # Add following settings log_errors=On error_log=/var/log/php/error.log
Disallow Uploading Files
If your application does not need to allow your visitor to upload files then disable the file upload. If your application needs to allow file upload then
- enable file upload
- restrict the upload file size
- make sure your application logic filters the file extension that your application needs
# Find the location of your php.ini php -i | grep "php.ini" # Open php.ini file from above location # Turn off/on your file upload settings file_uploads=On upload_max_filesize=1M # To disable file upload file_uploads=Off
Turn Off Remote Code Execution
To prevent attacker to execute php files remotely open your php.ini settings and turn off the following settings:
# Find the location of your php.ini php -i | grep "php.ini" # Open php.ini file from above location # Save following configurations allow_url_fopen=Off allow_url_include=Off
Enable SQL Safe Mode
If turned On, mysql_connect() and mysql_pconnect() ignore any arguments passed to them. Let's have a look at the example:
# Find the location of your php.ini php -i | grep "php.ini" # Add following settings # To your php.ini file sql.safe_mode = On # Define following variables # Make sure you change the variables # Add these lines to your php.ini mysqli.default_host = "127.0.0.1" mysqli.default_port = "3306" mysqli.default_user = "root" mysqli.default_pw = "Password123"
Now, when you have these configs in your php.ini file you do not need to define these variables during runtime. See below example:
# this line should be replaced $db = new mysqli( "127.0.0.1", "root", "Pass123", "database_name", "3306" ); # with this line # you don't need to pass above variables $db = new mysqli();
Note: This feature has been REMOVED as of PHP 7.2.0.
Control Form POST Size
When a form is submitted via post request in php make sure you limit the size of the form data. Open your php.ini file and add following setting:
; Set a realistic value here post_max_size=1K
The 1K sets max size of post data allowed by php apps. This setting also affects file upload.
To upload large files, this value must be larger than upload_max_filesize.
Resource Control (DoS Control)
Resource Control (DoS Control)
You can set maximum execution for your php script to proper value. This prevents long file execution if someone is running a script for long time:
Open your php.ini file and update these settings:
# set in seconds max_execution_time = 30 max_input_time = 30 memory_limit = 40M
Disabling Dangerous PHP Functions
To disallow dangerous function to prevent server attack disable some of the dangerous functions in your php.ini file:
disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source
PHP Fastcgi / CGI – cgi.force_redirect Directive
The configuration directive cgi.force_redirect prevents anyone from calling PHP directly with a URL like http://xyz.c/cgi-bin/php/hackerdir/backdoor.php.
; Enable cgi.force_redirect for security reasons in a typical *Apache+PHP-CGI/FastCGI* setup cgi.force_redirect=On
Limit PHP Access To File System
Following php.ini setting will allow php to access file within a specified directory, If a file is outside of the paths defined, PHP will refuse to open it.
; Limits the PHP process from accessing files outside ; of specifically designated directories such as /var/www/html/ open_basedir="/var/www/html/"
How Do I Search PHP Backdoors?
Followings are some of the commands to find any backdoors in your app:
grep -iR 'c99' /var/www/html/ grep -iR 'r57' /var/www/html/ find /var/www/html/ -name \*.php -type f -print0 | xargs -0 grep c99 grep -RPn "(passthru|shell_exec|system|base64_decode|fopen|fclose|eval)" /var/www/html/
Restrict File and Directory Access
Make sure your webserver root location has only permissions that you need:
# Allow read only permission chmod -R 0444 /var/www/html/ # Mac OS HTTPDUSER=$(ps axo user,comm | grep -E '[a]pache|[h]ttpd|[_]www|[w]ww-data|[n]ginx' | grep -v root | head -1 | cut -d\ -f1) sudo chmod +a "$HTTPDUSER allow delete,write,append,file_inherit,directory_inherit" /var/www/html sudo chmod +a "$(whoami) allow delete,write,append,file_inherit,directory_inherit" /var/www/html # Linux OS HTTPDUSER=$(ps axo user,comm | grep -E '[a]pache|[h]ttpd|[_]www|[w]ww-data|[n]ginx' | grep -v root | head -1 | cut -d\ -f1) sudo setfacl -dR -m u:"$HTTPDUSER":rwX -m u:$(whoami):rwX /var/www/html sudo setfacl -R -m u:"$HTTPDUSER":rwX -m u:$(whoami):rwX /var/www/html
Session Path
Make sure to update upload temp location and session save path as per your need:
# Path for session data session.save_path="/var/lib/php/session" # Temp upload file location upload_tmp_dir="/var/lib/php/session"
I hope you like this tutorial do share and like if you are blown with this article.