Blog Journeys of a Lifelong Learner
Subscribe
A Simple Apache/PHP Security Enhancement December 19, 2009
Web application development requires the consideration of various security issues.
SQL Injection and session hijacking are among the more popularĀ attack methods and must be carefully battled by web developers.
I used a custom PHP/MySQL web application for a recent web development project and decided to use Apache's mod_rewrite and some custom PHP code to reduce potential vulnerabilities.
I used the following rules in .htaccess:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^(.+)/$
RewriteRule ^(.+)/$ /$1 [R=301,L]
RewriteRule ^([a-zA-Z/-0-9]*)$ index.php?q=$1 [L,NC]
These lines enable mod_rewrite and set the base path for rewritten URLs:
RewriteEngine On
RewriteBase /
This line permits direct file URLs to be directly accessed but forces all other paths to be re-routed through the remaining rules:
RewriteCond %{REQUEST_FILENAME} !-d
This line forces all trailing slashes to be removed from URls (e.g., http://mysite.com/path/ redirects to http://mysite.com/path):
RewriteCond %{REQUEST_URI} ^(.+)/$
RewriteRule ^(.+)/$ /$1 [R=301,L]
RewriteCond %{REQUEST_URI} ^(.+)/$ forces all URLs containing trailing slashes to be redirected to the same URL without the trailing slash, as generated by RewriteRule ^(.+)/$ /$1 [R=301,L]. A 301 redirect is used, indicating that the new URL is the permanent location for the requested content.
This line causes all requests to be routed through index.php, the script which handles the loading of appropriate content based on URL strings:
RewriteRule ^([a-zA-Z/-0-9]*)$ index.php?q=$1 [L,NC]
Question marks (and ampersands) are not included in the RewriteRule, so URLs containing question marks and/or ampersands are not redirected through index.php. Since all GET queries use question marks (with ampersands for multiple variables), this RewriteRule eliminates the possibility of having a GET request transmitted to index.php through mod_rewrite.
I wrote index.php to check whether accessed URL is indeed one redirected through mod_rewrite:
if ((strpos($_SERVER['REQUEST_URI'], 'index.php?')) || (strpos($_SERVER['REQUEST_URI'], '?'))) {
die('Hacking attempt Detected! Cease and desist from your evil deeds!');
}
This code checks whether the requested URL (identified by $_SERVER['REQUEST_URI']) contains the string index.php or a question mark. In either case, script execution is immediately interrupted and an error message is displayed.
It would be possible to significantly expand this to generate a report containing the offending visitor's IP address and session information, but these Apache settings and PHP conditional operations eliminate many vulnerabilities in a simple way.
If you are developing a simple web application and do not intend to permit GET requests, I strongly recommend implementing a policy of permitting no question marks in request URLs.