Check your themes and plug-ins
It’s not just plug-ins designed for malicious purposes that pose a threat to your website. Plug-ins designed to be genuinely useful are sometimes coded in a way that makes it easy for hackers to abuse and access your website in ways that were unintended.
One example of how genuine plug-ins can accidentally introduce security issues to your website is TimThumb, a script that was developed for the WordPress theme Mimbo Pro to allow for automated image cropping and resizing. TimThumb was found to be highly useful for users of WordPress and was subsequently adopted for inclusion in many other WordPress themes as well as other open-source systems. The problem with TimThumb was that it originally didn’t validate the types of files being uploaded through it, and so allowed for PHP and other scripts to be loaded. This meant:
- There was a huge vulnerability in WordPress websites and open-source systems that were using themes that included TimThumb.
- Many users with themes using TimThumb were not aware how their website was affected, and this has resulted in reported claims of 1.2 million websites being affected.
- Hackers would be able to identify vulnerable websites simply by searching for WordPress websites using themes that were known to use the TimThumb script.
- The standard code structure of WordPress meant that hackers could produce automated ‘bots’ that scour the Internet looking for vulnerable websites to attack.
The result of the vulnerability meant that many website owners were caught unaware of the vulnerability, and had their website injected with anything from phishing code designed to steal information such as user login and credit card details, through to addition and injection of server-side code designed to hijack the server and send spam emails – or worse.
Williams tells how she minimises the security risk to her WordPress websites by being selective with plug-ins: “I’m actually quite careful with plug-ins, only going for those with the best reviews if possible. But nothing is foolproof, especially when things are open-source and anybody can muck about with them!”
Key actions to take when using any plug-in or theme with your open-source system include:
- Check the reviews and scores given to all themes and plug-ins you are considering using.
- It’s very easy to do this for plug-ins downloaded from wordpress.org – check the right hand column on the download page of your desired plug-in to see the number of reviews and average rating, keeping in mind the more ratings a plug-in has received the more trusted the rating average will be.
- Make sure you download your plug-ins from reputable sources.
- Your first port of call for WordPress plug-ins should always be www.WordPress.org/extend/plugins.
- Use Google to search for what other WordPress users are saying about the plugins you are considering using.
- Do specific searches relating to the plug-in and security vulnerabilities such as ‘TimThumb plug-in exploit’.
- Continue this on a regular basis for every theme and plug-in you use after you have completed your WordPress website, to ensure your website isn’t at risk from being affected by newly identified vulnerabilities.
- Ensure that your websites are using the latest versions of themes and plug-ins to avoid being caught out by vulnerabilities identified after you have created your website.
- If using WordPress, you can check for regular backend updates from your WordPress admin area, whereas one of many handy plug-ins can also be installed to send you an email notification on the same day that new updates are released.
- Other open-source systems have similar update notification features to WordPress – if yours doesn’t, simply check manually at least once a month via Google for each plug-in you are using.
- Avoid going trigger-happy with plug-ins.
- The more plug-ins you use, the more chance there is of something going wrong and the more time you have to spend ensuring your websites are using the latest version.
Exploits can happen to any plug-in, and just because it hasn’t yet doesn’t mean it wont. A knee-jerk reaction to using TimThumb would be to replace it. However, there is no guarantee that your chosen script doesn’t suffer equally. Now the particular vulnerability in the TimThumb example has been patched, it would arguably be safer to use the latest version of TimThumb over an equivalent unknown plug-in because at least it can be confirmed that the issue has been secured.
Admin area and keeping updated
Having your admin area URL and standard admin login name kept as the default is looking for trouble. By renaming the ‘wp-admin’ folder and changing or deleting the default ‘admin’ username, you make your WordPress login area more secure.
Nick Stockbridge, director of Transmedia (www.transmedia.co.uk) a WordPress training provider, tells us how even basic measures can be used to secure WordPress websites:
“As WordPress is such a popular blogging platform and simple CMS, it has become a target for hackers to exploit vulnerabilities in WordPress installations that have older versions or poor security. Most delegates on our courses are concerned with security and are interested in best practice for securing WordPress. Basic measures include keeping your WordPress installation up to date, installing into a location other than the default one and using secure passwords and usernames.”
Adjusting your server settings
Whether it’s through third-party plug-ins, or code developed by yourself or your team, it’s not always possible to ensure that all code used in your WordPress installation can be trusted to be a hundred per cent secure. A first measure of defence is to make your hosting stop any undesired activities regardless of what is in the code. This means that even if you accidentally install a malicious plug-in that is designed to hijack your website, the attack will be stopped immediately through the restrictions placed in your server settings.
Modifying PHP Behaviour for File Operations
We’ve already looked at how we can restrict scripts from doing things we don’t want them to, but as mentioned in the original web security article in Web Designer #187, it’s always better to have something to fall back upon should something fail. If your hosting allows it, you can create or edit an existing settings file called ‘php.ini’ that controls how PHP works. The main setting you want to look at is:
- When set, this limits PHP to operating on files in specific directories. This is very useful for stopping scripts from copying themselves throughout your WordPress installation and injecting malicious code into themes and other files your website uses. Update this in your php.ini file by looking for ‘open_basedir =’ – if there is a semicolon before it, take this out. Replace this line with something similar following, where the actual path reflects the true path to your WordPress uploads folder:
001 open_basedir = ‘/home/www/public_html/ wp- content/uploads/’
- Caution: Modifying this setting will stop file functions outside of the uploads directory from working, so you have to specify other directories that you wish to allow file operations within the open_basedir setting. You do this by separating each directory with a colon, hence if you also wanted to allow Plug-inA to be editable, open_basedir would look like:
001 open_basedir = ‘/home/www/public_html/ wp- content/uploads/:/home/www/public_html/ wp- content/Plug-inA/’
- Caution: Although open_basedir is very useful for limiting PHP scripts to what they can do, it is only a setting for PHP, so it will not limit scripting files of other languages such as Python.
Plug-in and theme development
The ability to develop your own functionality is what makes open-source systems like WordPress so
flexible. However, it’s almost as important to keep an eye on plug-ins you develop yourself as it is for those created by other people.
Server side vs client side
Information kept on your server is more secure than anything you may expose as hidden information within HTML forms or URL query strings. Information you may not want to reveal but are required by processing scripts when the user submits information, is tempting to place within hidden fields of an HTML form. This is a basic way to do the job, but provides big security risks that allow hackers to tamper with data in your hidden fields and also exposes details about how your plug-in works.
Instead of relying on providing system sensitive information via HTML forms, a better strategy is to keep such information on the server, providing the advantage of ensuring it can’t be tampered with by the end user and also avoiding revelations of how your code works behind the scenes. This style of processing can be achieved in a number of ways – the most basic is to use server sessions, which can be activated by using PHP’s session_start() function and $_SESSION values:
Server sessions are a good way to keep data on the server that is specific to the current user, but sometimes you may need a more robust solution to access data that is relevant to all users. One example would be information for product processing for some type of eCommerce plug-in. By creating a table for data profiles, you can store your data as a JSON string using PHP’s json_encode() function and use a hidden field in the form to store the record ID to find the processing information. This allows you to process the same information, but by only revealing the data profile ID.
Verification with tokens
When you are processing any data, especially critical data such as payment confirmations, you need to ensure that the information provided is genuine. Tokens are a verification code generated by your script that are used to verify that returned information is what it should be. Make your system more secure by generating tokens to validate authenticity of returned important data. Combining this with server-side data profiles will ensure that hackers can’t fool your system into processing the wrong data profile.
Creating a token can be achieved by producing an MD5 hash. This is done by combining information you want to verify with information known only by the server – such as the user login time and secret password. The following code shows how this could be done with PHP:
001 $token = md5($data[‘id’] + $_ SESSION[‘loginTime’] + $systemPassword);
Verify file types
When accepting file uploads with your code, you should always check to see what type of files are being uploaded. The aforementioned TimThumb script was designed to work with image uploads, but a failure to check the types of files being uploaded opened a vulnerability that allowed PHP scripts to be sent and run on the server. At first glance, the obvious solution to the problem would be to put a ban on PHP files being uploaded through the script, but this still leaves huge holes for other types of scripting and executable file types such as Python that the server may support. Instead of relying on creating a large list of file types to ban, the hundred per cent secure solution is to validate all file types against what you will accept, leaving no scope for your code to accept anything threatening.
Eval() is Evil()
Programmers are sometimes faced with scenarios that can benefit from being able to embed PHP code within content, such as creating calculations and performing server functions from content stored within a database. Those who are not aware of the security implications of this would see PHP’s eval() function as an opportunity to open many opportunities for dynamic data processing sent from the database. The problem with this is that if the database is hacked, the nature of open-source plug-ins will also mean that the hacker will know (or be able to guess) which parts of the database are used to store PHP code that gets executed; from this, all they would need to do is update or insert a record that has PHP code to do anything they want, including:
- Find your installation settings and email it
- Write new scripts on the server that open vulnerabilities for the hacker and their automated tools to attack.
- Inject PHP scripts with malicious phishing code.
- Stealing content files via email.
The solution to this problem is not to use eval() in the first place. Instead, use a more sophisticated approach, one that allows your content to have triggers that call processing scripts and generate results to be placed into the content, giving you full control of what code is being processed. These triggers would contain the information your content needs for dynamic processing information and so would still provide you with the abilities your code needs to solve the problem at hand.