WordPress or WP as I call it went viral long ago, with 54% or all CMS systems using WP it’s obvious it’s not a fad. But with that many people using the code, you also have lots of people now vulnerable to a whole slew of attacks. Because WordPress is so easy to use, many people create quick blogs without putting very much time into thinking about security.
This is true not only of the people setting up the WP sites but also the people creating plugins and themes. As I look through WP plugins I see more than 50% of the code had no security accounted for. I hope to point out several of those security issues as well as better prepare you for deploying your own WP site.
First off before you can even think about setting up a secure WP Site, you have to have a secure webserver. Believe it or not it really doesn’t matter all that much if you use Apache or IIS7.0. I hate to say it, but don’t congratulate Microsoft on this accomplishment. It’s really the PHP dev team who made PHP a solid product on IIS. For this article though we will be focusing on Apache + PHP.
If you are going to be running multiple WP instances controlled by different people then you really want to look into using something like suExec or suPHP. These modules allow you to run the php script as the user who owns the file. This is a big security feature as typically any script that is run is run as the webserver. This means any script could in theory hurt any other script that is running since their is no seperation (aside from processes). Also in order to make it accessible by Apache and your customers the script would have to have more relaxed file permissions.
suExec and suPHP fix this by running your script as the person who owns the script. Think of this as a little sandbox to separate your various WordPress Instances. When a user ftp/sftp into your server to upload files to your server, those files will run as the user who uploads them. It also makes it perfectly acceptable to tell your ssh & sftp server to lock the users into their home directories to prevent them from playing dangerous on your server.
Note though, this doesn’t really work for you if you are using WordPress Multiuser. This is because WordPress Multi-User all runs as a single WP instance (everything as one user). When deciding if you want to run WP Multiuser or multiple instances of WP you should think about the logical separation of who it’s for. If you need multiple sites for the same company, then use WP Multiuser. If you are looking to go more of a shared hosting route then you should really use multiple instances of WP as this is safer for your customers.
The php.ini holds a lot of power in PHP. It also hold the most power when it comes to security. This is the place where you should make the big changes. Such as….
.htaccess is an amazing little feature of apache that allows you to control several apache runtime configurations. This is a great way to restrict access to certain folders in your site. For example you can lock your wp-admin directory to only be accessed by specific ip address with something like the following.
order deny,allow deny from all allow from xxx.xx.xx.xxx
You can also use the .htaccess to disable register_globals if you dont have control over the php.ini file by placing php_flag register_globals off in your .htaccess file
Many people have asked me what the file permissions are supposed to be for WP. Before I give my recommendation I want to explain some things you need to consider. Unless you are using suExec or suPHP your WP is running as the webserver user. This means that if you have a script that uploads files for edits files (like WP) then the webserver needs to have access to write to your files. Now most of the items in WP that get modified exists under the wp-content directory. So in my opinion I would make all the files owned by either root or the user who manages the WP files. Then set the wordpress permissions with the following command.
chmod -R 655 wordpress
After this we must modify the wp-content subdirectory permissions. (Note: If you are using suExec or suPHP the previous permissions are enough, skip the rest.)
If you have root access set the group permissions of the files to the webserver group.
chgrp -R apache wp-content chmod -R 775 wp-content
If you don’t have the ability to set the permissions to the webserver group then do the following with extreme caution.
chmod -R 777 wp-content
I must point out that setting any directory in your web path to 777 is a security risk. At those permissions any files within are a free for all. If you don’t find giving your ftp password everytime you make a change you could also leave those permissions at 777 and just put in your ftp username and password each time you need to upload plugins for themes.
By far one of the most successful web security tools no matter what application you are running is mod_security. I can’t stress how amazing this Apache module is (I believe it has an IOIS version also) This module basically works as a firewall for your webserver. It actually inspects every request that comes into your server and searches for potential attacks in the request. It has a very high detection rate (sometimes to high). I can say for sure that this tool has saved some of the larger web sites I’ve run.
It has several version including an opensource community edition. USE THIS!
Always stay up to date on your system patches. This is critical, don’t let your WP get compromised from your operating system or it’s applications (IE. apache, mysql, ssh etc)
Also make sure to keep your WordPress install current. When you see the update notice, follow it and run the update.
The one thing I’ve seen was looked over by every site I’ve been called into repair, is they didn’t do proper backups. This can and will save you SO much money. It will also help you get your site back online faster. Make sure that you backup both your database and your actual files.
Once you have a secure server setup, then you need to really take the time to lock down Wp from the inside. The following are the tips I follow.
Security in WP can also be increased by certain plugins. Here is a great list of plugins to help.
The biggest problem with the Security of WP is not the core code, but the plugins and themes. As a plugin or theme author you should know about these api functions by heart https://codex.wordpress.org/Data_Validation These functions are the data validation functions. They are how you test to make sure that the data coming from the user is safe to use. Lack of input validation is responsible for most security bugs like cross site scripting (XSS) or SQL Injections.
Below are my personal coding tips for making secure plugins and themes.
function printWelcom($name = false){
if(isset($name) && !empty($name)){
print "Hello ".esc_html($name)." welcome back!";
}
}
This serves many purposes, first it makes sure that you will never receive those pesky notices in your php log about PHP Notice: Undefined index: name in. It also makes sure you didn’t make a typo in variable name. Finally notice the use of the esc_html function. This is one of those input validation functions discussed above. It makes sure that what ever they send doesn’t contain malicious code the could cause a XSS attack.
Order Allow,Deny Deny from all <Files ~ "\.(css|jpe?g|png|gif|js)$"> Allow from all </Files>
In this example only javascript, css and images are allowed. This will prevent people from directly calling any php scripts.
If you have a security recommendation. Place it in the comments below. If you are confused about one of the recommendations, let me know and I’ll break it down more for you.
See Also
http://aymanh.com/checklist-for-securing-php-configuration
Jimmy Fredrickson says: [January 28, 2012 at 4:17 pm ]
Filtering your inputs yourself rather than trusting the efforts of plugin writers or even the main CMS authors themselves, many of whom have little idea about database injections and XSS and the like. Here is an addon I like using as it filters the GET requests and cookies real well. http://pastebin.com/wiibvZfW