Note: This is still a work in progress. I will gradually add items to the list. You are welcome to contribute your points. Thanks.
To begin, we shall first follow Configuration steps for a more secure site. Then we can do the rest as listed below.
Harden Your Web Server
Harden the web server's setup and configuation
Hide PHP
Here is howto configure php securely. Especially:
- In /etc/php.ini, find the line "expose_php" and set the value to "Off".
- In /etc/php.ini, set "display_errors" to "Off", and "log_errors" to "On".
Remove unwanted modules
Especially, since Drupal-5 and 6 require PHP-5.1.6 and up, you should make sure you remove php3/4 modules.
Setup application-layer firewall
mod_security 2.5 is available now.
In your Drupal website, if your content has <?php> in it then it will probably get flagged as a security error, and hence receive "internal server error". Please bear that in mind.
Note: I saw this page on drupal and mod_security, but I don't know what it is for: http://kb.ozlinux.com/article.php?id=014&pt_sid=86ac4198a039311c9dd30b78...
Harden Your File Systems
Edit /etc/fstab. For the file systems /shm/dev, /tmp, /var, and /home replace the "defaults" with "noexec,nodev,nosuid"
noexec : Binaries are not allowed to be executed. NEVER use this option for your root file system!
nosuid : Blocks the operation of suid, and sgid bits.
nodev : Prevent any user to mount the file system.
If you don't have /var on its own mount point, delete /var/tmp and have it linked to /tmp by doing "ln -s /tmp /var/tmp"
After you updated /etc/fstab, run "mount -a" to refresh.
Harden Your Drupal Installation
Remove unwanted files
After you have successfully installed your drupal, you can safely remove these files:
CHANGELOG.txt, COPYRIGHT.txt (drupal 6), INSTALL.pgsql.txt, LICENSE.txt, UPGRADE.txt, INSTALL.mysql.txt, INSTALL.txt, MAINTAINERS.txt, and install.php
Secure your upload area
- Never leave your "files/" upload directory with world writable permission on.
- Go back to your apache httpd.conf or your virtual host's configuration file, and add the section:
<Directory path_to_your_doc_root/files>
php_flag engine off
SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006
Options None
Options +FollowSymLinks
</Directory>
If you use lighttpd, then you need to add the following:
# if your path the upload directory is /foo/files, then replace "files" in the next line with "foo/files"
$HTTP["url"] =~ "^/files" {
cgi.assign = ()
fastcgi.server = ()
scgi.server = ()
}
- If you have multiple sites, and each site has its own upload "files" directory, then you must add the above code for every single "files" directory.
- Then restart your web server. This will make sure no php files or any arbitrary scripts get executed off your file upload area.
Move .htaccess into your web server's configuration file
If you followed the hardening Apache suggestion, you would have turned off "AllowOverride". Now it's time to copy the rules in your .htaccess into your apache httpd.conf or your virtual host's configuration file.
Inside your upload area "files/" directory, you also get an .htaccess from Drupal. Please examine that and see if you need to put that into your web server's config file.
Everytime you upgrade the Drupal core, please verify that the changes in .htaccess is copied into your web server's httpd.conf file as needed.
Secure Drupal Configuration
Drupal error
In "Site configuration" -> "Error reporting", set "error reporting" to "write error to log". This helps to prevent revealing your filesystem structure when drupal error is encountered.
Access control
- If you have private user group, then make sure you uncheck everything, execpt "view content" and its siblings, for anonymous users.
- Review your access control periodically and make sure all are set properly.
Drupal best practices
http://drupal.org/best-practices has some suggestions on Drupal best practices. Please check it out.
Beware the Securities of Contributed Modules
I've often seen dangerous code in contributed modules. So be on your guard. One simple way to find out about sql-injection vulnerabilities, is to do a "find . -type f -exec grep db_query {} /dev/null \;" from inside your module directory, and see whether the variables are passed in as parameters or as part of the SQL query string.
For any modules that allow for upload, please test and make sure it will not allow random uploading executibles. One popular image upload module I've tested, allowed me to upload a .php file even though the configuration forbid the action. Everytime you upgrade these modules, please make sure that you test again.
Keep up with Drupal Upgrade
- Signup in drupal.org, and subscribe yourself to the security alert. This ensure you are informed whenever security upgrade is available.
- Install the module "update_status", which will alert you whenever new version is available in any of your installed modules. The function of this module is now part of Drupal-6 core.
- Always keep all of your modules up to date, even when the module upgrade is not security upgrade. This will make your life easy in case a security upgrade is needed. When you try to upgrade a module while skipping a few versions in between, you are more likely to hit broken upgrades. That's why I prefer to keep the versions up to date.
Protect Your Administration
- Purchase an SSL certificate.
- In your apache.conf, add the lines below to force all traffic to /user and /admin go through https:
php_value session.cookie_secure 1
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^/user(.*) https://%{SERVER_NAME}/user$1 [R,L]
RewriteRule ^/admin(.*) https://%{SERVER_NAME}/admin$1 [R,L]
</IfModule>
If you use lighttpd, add the lines below: (Reference http://redmine.lighttpd.net/wiki/lighttpd/Docs:ModRewrite to understand why we have to add rules to both url.rewrite and url.rewrite)
url.redirect = (
"^/(user.*)" => "https://www.domain.com/$1",
"^/(admin.*)" => "https://www.domain.com/$1",
)
url.rewrite-final = (
"^/(user.*)" => "$0"
"^/(a.*)" => "$0"
If you have virtual host, add the section above to your virtual host configuration.
- Set up VPN or SSH-tunneling to protect admin access via SSH. If you don't have VPN or SSH-tunneling available, use IP whitelist to limit SSH access.
- If your user group is private, you can also apply VPI, SSH-tunneling, or IP whitelist to limit access to port 443, the HTTPS access.
- Secure your update.php, and limit access to update.php to SSL (https) only. Since update.php can only be run as #1 user, you can also add access with IP restriction into the web server's config file.
For banning access to http://yoursite.com/update.php, do something like this:
<Files ~ "/update.php$">
Order allow,deny
</Files>
For limitting access to https://yoursite.com/update.php, do something like this:
<Files ~ "^update.php$">
Order deny,allow
deny from all
allow from xxx.xxx.xxx
</Files>
(replace "xxx.xxx.xxx" with your IP.)
With lighttpd, you would do something like this:
$HTTP["host"] == "www.example.org" {
$HTTP["remoteip"] !~ "10.0.0.0/8" {
url.access-deny = ( "" )
}
}
Learn How Website Hacking Works
Here are some videos that show you how to hack websites:
Recent comments
8 weeks 4 days ago
9 weeks 3 days ago
20 weeks 3 days ago
21 weeks 6 days ago
30 weeks 4 days ago
30 weeks 5 days ago
31 weeks 5 days ago
32 weeks 4 days ago
32 weeks 4 days ago
32 weeks 5 days ago