Securing Your Craft Site in 2021—Part 2

January 26, 2021
by Ben Croker

Using software you trust is key to increasing your chances of keeping your site secure and lowering the chances of introducing a vulnerability. But how exactly do you know which software (and developers) are trustworthy and which are not?

Securing your craft site

In part 1, we discussed the importance of prioritising software updates as the easiest and most effective strategy in keeping your site secure. By using software developed by people and organisations you trust, you can be more confident that they:

  1. Have taken steps to ensure that the latest version of their software is secure.
  2. Are actively maintaining and improving their software.
  3. Will react accordingly and responsibly in case a vulnerability is found.

Create a Safe List #

Assuming you are using Craft CMS to build your site, you should already have confidence in Pixel & Tonic, so we can go ahead and add P&T to the safe list”. This can include Craft as well as first-party plugins such as Commerce, Feed Me, etc.

Not many people know that Craft offers bounties to anyone who reports a security vulnerability in Craft and first-party plugins. This is a great way to incentivise security researchers and developers alike to discover and report issues appropriately and discreetly.

Next, come third-party plugin developers. Since any Craft plugin you use will have access to all parts of the CMS, including the database, file system and environment variables, it is vital that you review each plugin before installing and blindly trusting. How you do this is up to you, but keep in mind that Craft’s own review process of plugins is, to the best of our knowledge, minimal. Here are the steps that I suggest you take, especially for plugins created by developers whose plugins you have not used in the past.

1. The Quick Scan #

Start by quickly scanning the plugin page in the plugin store. Does it have a respectable description, changelog and screenshots? Check the version number (be wary if at 0.x.x), the last update (should ideally be in the past 3 months) and the active installs (ideally 100 or more). Take a quick look at the other plugins this developer has released by visiting their plugin store developer page as well as their website.

Plugin Page Example

2. Docs & Support #

Next, visit the plugin’s documentation. Is it well explained, structured and thorough? Is there a clear path to receiving support if something goes wrong? Visit the plugin’s GitHub page and look at the Issues” tab. Are issues being responded to in a timely and helpful manner? You may find yourself here again at some stage with an urgent support request, so be sure to do your due diligence now.

3. Free vs. Commercial #

Consider whether the plugin is free or commercial. A free plugin may seem appealing as it requires no financial investment, yet the time investment (and hair-pulling) may be significant if it turns out to be someone’s hobby project which they no longer have time to support. A commercial plugin doesn’t necessarily guarantee better quality or support, but since the developer is financially incentivised to maintain and update the plugin, there’s a better chance that it will. Remember that security is all about stacking the odds in your favour.

4. Read Reviews #

While the plugin store doesn’t have a rating or review system, many people in the community write about their experiences using plugins, which can be invaluable information to have. Some examples include:

Most reviews are generally positive and it is quite rare to find a critical one, but now and then you will overhear a conversation about a developer being burned by an unmaintained plugin.

You get what you pay for

There Will Be Dependencies #

I went on enough about the dangers of dependencies in part 1, so I’ll just reiterate that if you choose to install a plugin, then you automatically agree to install all of its dependencies. There is no way around this. If Craft has a dependency on the Yii framework (which it does), then your site will be running on the Yii framework. Similarly, if plugin X depends on packages Y and Z, then installing plugin X will also install packages Y and Z.

So we need to accept that trusting a plugin inherently means trusting its dependencies, whether or not we know anything about them at all. This may be risky territory to find ourselves in, or blissful ignorance, depending on how you look at it.

Composer to the Rescue #

Fortunately (or unfortunately, as some might say), Craft uses Composer for its dependency management, which gives us a centralised way of managing and determining which PHP packages will be installed on the web server. Understanding the basics of Composer and its version constraints is essential for anyone who calls themselves a Craft developer. For an introduction to working with Composer in Craft, read this section of Setting up a New Craft CMS 3 Project.

Composer 2.0 was released in October 2020 and is a huge improvement in terms of performance. How dependency updates are done is also more deterministic, which helps prevent errors and results in a more robust update process. Craft fully supports Composer 2 (provided you require craftcms/plugin-installer version 1.5.5 or above) and you should use it wherever possible.

I can’t overstate how important a basic understanding of Composer is, so do yourself a favour and go refresh your knowledge regularly. You’ll likely find that you learn something new each time. The version constraints you really must understand are as follows.

Exact Version Constraint #

3.1.0

Tells Composer to install this version and this version only. Craft uses exact versions when you perform Craft and plugin updates from the control panel or the console.

Version Range #

>=2.6 <3.0

Tells Composer that one or more ranges of valid versions can be installed. Useful for dependencies but should be avoided for Craft and plugins.

Tilde Version Range (~) #

~3.1.0

Tells Composer that any version between 3.1.0 and up to but not including 3.2.0 can be installed (equivalent to >=3.1.0 <3.2.0). Useful when you want to only allow bug fixes or patch version updates (version Z in x.y.Z) according to semantic versioning.

Caret Version Range (^) #

^3.1.0

Tells Composer that any version between 3.1.0 and up to but not including 4.0.0 can be installed (equivalent to >=3.1.0 <4.0.0). Useful when you want to only allow backwards-compatible updates or minor version updates (version Y in x.Y.z) according to semantic versioning. Provided the plugins you require use semantic versioning (they really should), the caret version range (^) will keep them as up-to-date as possible without introducing breaking changes.

Platform Requirements #

Composer gives you the ability to specify which PHP version your web server is running, which ultimately determines which versions of packages and dependencies are installed (since they can each have their own minimum PHP version requirements). By default, Craft adds a PHP platform requirement to your project’s composer.json file when it is installed. Craft 3.0.0 and above sets it to 7.0, while Craft 3.6.0 and above sets it to 7.2.5 (the minimum PHP version requirement was increased in Craft 3.6.0).

Having a PHP version in your project’s composer.json that is lower than the version that is running on your web server may result in Composer not installing the latest version of dependencies. This is a dangerous way to live!

Regardless of what Craft sets the default PHP version to, you should change the version to reflect that used on your production web server. Doing so will ensure that the latest versions of dependencies will be used, according to their PHP version requirements. 

  "config": {
    "sort-packages": true,
    "optimize-autoloader": true,
    "platform": {
      "php": "7.4.14"
    }
  },

The Sherlock plugin automatically checks that the PHP version in your project’s composer.json is the same as the version that is running on your web server and warns you if it is not.

PHP Composer Version Test

Underlying Software #

Up until to now we have been mostly concerned with trusting Craft, plugins and their dependencies. But there is another layer of software that is just as important to keep secure, and that is the web server itself. I use the term web server” broadly here to refer to the actual web server (Apache, Nginx, etc.), the database server (MySQL or PostgreSQL), PHP and its extensions, as well as any supporting services such as Redis, Memcached, etc.

This is a lot to cover and goes beyond the scope of this article, but here are a few considerations to keep in mind. 

  1. Shared hosting (the traditional form of it, in which you share a physical server’s resources with other users) is rarely if ever going to be secure, simply due to the nature of shared resources. Please avoid and save yourself the hassle!
  2. VPS hosting is a good middle-ground, provided you know what you are doing or you use a reputable provisioning service such as Laravel Forge, Server Pilot or Ploi. While some security updates and patches can be set to run automatically, others cannot. With this hosting option, you are the one responsible for updating the server and dealing with any DevOps issues that arise. 
  3. Managed hosting offers the best all-round value. With managed hosting, you get a web server that is optimised for speed and scalability (in some cases specifically for running Craft CMS). You need not be concerned with installing or configuring services, as this will all be done by your hosting provider according to their opinionated best practices (including things such as network stack security, DDoS handling, performance kernel tweaks, SSH configuration, etc.). Server updates will also be applied for you in a timely, non-breaking manner. And lastly but most notably, you can almost always get hold of another human on the other end if something goes wrong and you need support. 

Check out the Hosting Craft CMS page for a round-up of officially recommended hosting providers. From that list, I can personally recommend Arcustech, Cloudways, fortrabbit and Servd.

Managed hosting providers

Upgrading your VPS #

Ironically, a vulnerability in sudo (which provides super user privileges) was announced on the same day this article was published. According to the CVE article published by Qualys, exploitation of this heap-based buffer overflow vulnerability allows any unprivileged user to gain root privileges on the vulnerable host”. Sounds pretty serious. 

If you use managed hosting, your hosting provider should be on top of things and have already patched the vulnerability. It was Nevin Lyne of Arcustech, in fact, who informed me of this vulnerability.

If you manage your own VPS, be sure to check whether you are running a vulnerable version of sudo and upgrade immediately if you are. Below are my recommended steps, which can be applied to upgrading the server in general.

Disclaimer: I am not an expert. This is what worked for me. If you don’t know what you’re doing, consult an expert.

  1. Backup the entire web server. Do not proceed unless you are absolutely sure that you can restore the web server if need be.
  2. SSH into your web server.
  3. Run the command sudo --version to check whether your version of sudo is affected. According to the article, versions 1.8.2 to 1.8.31p2 and 1.9.0 to 1.9.5p1 are affected.
  4. Run the command sudoedit -s / (entering your password if prompted). If the response starts with sudoedit:, the system is vulnerable. If the response starts with usage:, the system is patched.
  5. If the system is vulnerable, run sudo apt update && sudo apt upgrade -y to upgrade all packages on the system.
  6. Run the commands in steps 3 and 4 to verify that the vulnerability was patched.
  7. Exit and SSH back into the web server. If you see the prompt System restart required” then you may need to run reboot to restart the server. This will cause downtime of any sites running on the web server. Be sure to have your backup restore strategy ready to go, just in case.

Have a Security Policy #

In part 3, we’ll discuss the importance of creating and enforcing a security policy. This can apply to a single site or to all the sites you develop, even to your entire company. But not having a security plan is like not having a data backup plan. Tell me you have a data backup plan!!

Part 3 of this article is coming in the near future.

Perform Regular Security Audits #

In part 4, we’ll discuss the importance of performing regular security audits. Remember how you used to have fire drills in school? They weren’t just a reason to get out of class, although that was a major bonus. 

It is only by regularly performing a security audit that you will be able to know whether everything you have done to secure your site and implement your security policy has been worthwhile. If you don’t have the capacity or skills to perform an audit yourself then bring in an external company to do it. External audits are often recommended over internal ones, as skilled people looking at your site from the outside are bound to see it differently and you are guaranteed to learn a ton from them.

Part 4 of this article is coming eventually, but don’t let that stop you from drafting a proposal to perform a security audit today!

Learn More #

Listen to this devMode​.fm podcast episode in which Infosec consultant Eugen Olteanu comes on the show to discuss Information Security: The Underbelly of the Beast.

Information Security: The Underbelly of the Beast

Image Credits #

Detectify Blog