User Tools

Site Tools


linux:securingphp

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
linux:securingphp [2011/08/12 20:54] rlunarolinux:securingphp [2024/02/05 13:57] (current) rlunaro
Line 1: Line 1:
 +====== Securing PHP ======
 +
 +Here is my configuration / notes about securing a php installation. 
 +
 +
 +===== Avoid common exploits =====
 +
 +These configuration rules are taken from the .htaccess file configuration of Joomla, and 
 +I've adapted it for apache. They address some common exploits. 
 +
 +<code>
 +
 +<IfModule mod_rewrite.c>
 +    RewriteEngine On
 +    
 +    ## Begin - Rewrite rules to block out some common exploits.
 +    # If you experience problems on your site block out the operations listed be
 +    # This attempts to block the most common type of exploit `attempts` to Jooml
 +    #
 +    # Block out any script trying to base64_encode data within the URL.
 +    RewriteCond %{QUERY_STRING} base64_encode[^(]*\([^)]*\) [OR]
 +    # Block out any script that includes a <script> tag in URL.
 +    RewriteCond %{QUERY_STRING} (<|%3C)([^s]*s)+cript.*(>|%3E) [NC,OR]
 +    # Block out any script trying to set a PHP GLOBALS variable via URL.
 +    RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
 +    # Block out any script trying to modify a _REQUEST variable via URL.
 +    RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
 +    # Return 403 Forbidden header and show the content of the root homepage
 +    RewriteRule .* index.php [F]
 +    #
 +    ## End - Rewrite rules to block out some common exploits.
 +
 +
 +    ## Begin - Joomla! core SEF Section.
 +    #
 +    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
 +    #
 +    # If the requested path and file is not /index.php and the request
 +    # has not already been internally rewritten to the index.php script
 +    RewriteCond %{REQUEST_URI} !^/index\.php
 +    # and the request is for something within the component folder,
 +    # or for the site root, or for an extensionless URL, or the
 +    # requested URL ends with one of the listed extensions
 +    RewriteCond %{REQUEST_URI} /component/|(/[^.]*|\.(php|html?|feed|pdf|vcf|raw
 +    # and the requested path and file doesn't directly match a physical file
 +    RewriteCond %{REQUEST_FILENAME} !-f
 +    # and the requested path and file doesn't directly match a physical folder
 +    RewriteCond %{REQUEST_FILENAME} !-d
 +    # internally rewrite the request to the index.php script
 +    # RewriteRule .* index.php [L]
 +    #
 +    ## End - Joomla! core SEF Section.
 +
 +
 +
 +
 +</IfModule>
 +
 +</code>
 +
 +===== per directory configuration =====
 +
 +Not all the directories of your website are the same; some of them must allow the 
 +execution of php, some others not. **In the case you have to allow php execution**, 
 +you have use "php_admin_flag engine On" to allow php execution in that directory: 
 +
 +<code>
 +<Directory "/var/www/YOUR-DIRECTORY/">
 +
 +    Options -Indexes +FollowSymLinks
 +
 +    AllowOverride None
 +
 +    php_admin_flag engine On
 +
 +    php_admin_value open_basedir "LIST-OF-DIRECTORIES-HERE"
 +    php_admin_value include_path "ALLOWED-INCLUDE-DIRECTORIES-HERE"    
 +    php_admin_value upload_tmp_dir "ALLOWED-TMP-FILES-HERE"
 +    # you can configure any php param here: 
 +    php_admin_value post_max_size "25M"
 +    php_admin_value upload_max_filesize "20M"
 +</Directory>
 +</code>
 +
 +==== Any other directory where won't be php files must have the php execution restricted ====
 +
 +PHP execution must be restricted in those directories where 
 +it's clear won't be any php file in them:
 +
 +<code>
 +<Directory "/var/www/MY-WEBSITE/UPLOADED-FILES">
 +    # To avoid c99.php injection
 +    php_admin_flag engine Off
 +</Directory>
 +</code>
 +
 +==== Even it's a good idea to restrict any request to some directories at all ====
 +
 +For instance, you can restrict the access to your logs directory of your website at all 
 +to avoid someone could guess the url and try to gain access to the logs content: 
 +
 +<Directory "/var/www/MY-WEBSITE/logs">
 +    <RequireAll>
 +        Require all denied
 +    </RequireAll>
 +    php_admin_flag engine Off
 +</Directory>
 +
 +==== Ohter directories must only be executed from inside your website ====
 +
 +Imagine you have a directory of php files you only want through a cron 
 +file: in that case, specify that those directory cannot be reached from 
 +any place, but from inside of the machine only: 
 +
 +<code>
 +<Directory "/var/www/MY-WEBSITE/RUNNING-FROM-INSIDE">
 +            <RequireAll>
 +                    Require local
 +            </RequireAll>
 +</Directory>
 +</code>
 +
 +
 +
 +
 +===== php_openbasedir must be configured per site =====
 +
 +In the apache configuration of the virtual host, **open_basedir** must be configured and must point 
 +to the directory of the web application or deeper, to ban php to open other files that aren't in the 
 +installation. 
 +
 +Example:
 +
 +<code>
 +    <Directory "/mywebsite">
 +        php_admin_value open_basedir "/mywebsite:/dev/urandom"
 +    </Directory>
 +</code>
 +
 +===== include_path must be specified also and limited to the web directory or deeper =====
 +
 +''include_path'' is another funny thing. It specifies what php files can be read by the 
 +''include'' command: it's better to specify the more constrained directory possible: if the 
 +application has an "include" directory, specify this directory only, to avoid an attacker 
 +to read configuration files or other information. 
 +
 +This configuration must be set per virtual host, and it's better to set a non-existent file 
 +in the main php.ini file. 
 +
 +Example:
 +
 +<code>
 +  php_admin_value include_path "/mywebsite/include/"
 +</code>
 +
 +
 +===== upload_tmp_dir must be set OUTSIDE YOUR WEBSITE =====
 +
 +**__This is a frequent source of problems__**. And I misunderstood that many times, until somebody
 +kindly let me know about this, by injecting c99.php in my website. This directive configures 
 +the directory where upload files must be placed when loaded: it's a very bad idea to have them 
 +inside your website, because it allows an attacker to upload any php file and execute it afterwards. 
 +
 +Example: 
 +
 +<code>
 +php_admin_value upload_tmp_dir "/tmp"
 +</code>
 +
 +
 +===== engine must be unset if the site doesn't need php  =====
 +
 +Configure ''engine on'' only if you need php in the virtual host: 
 +
 +Example: 
 +
 +<code>
 +php_admin_value engine On
 +</code>
 +
 +In any other website, turn it off. 
 +
 +
 +