(This article was cross-posted on lullabot.com.)
Drupal has a great reputation as a CMS with excellent security standards and a 30+ member security team to back it up. For some Drupal sites, we must do more than just keep up-to-date with each and every security release. A Drupal site with private and confidential data brings with it some unique risks. Not only do you want to keep your site accessible to you and the site’s users, but you also cannot afford to have private data stolen. This article provides a checklist to ensure the sensitive data on your site is secure.
Keeping a Drupal 8 site secure requires balancing various needs, such as performance, convenience, accessibility, and resources. No matter how many precautions we take, we can never guarantee a 100% secure site. For instance, this article does not cover vulnerabilities beyond Drupal, such as physical vulnerabilities or team members using unsafe hardware, software, or networks. These suggestions also do not ensure General Data Protection Regulation (GDPR) compliance, a complex subject that is both important to consider and beyond the scope of this checklist.
Rather than systems administrators well-versed in the minutia of securing a web server, the list below targets Drupal developers who want to advise their clients or employers with a reasonable list of recommendations and implement common-sense precautions. The checklist below should be understood as a thorough, though not exhaustive, guide to securing your Drupal 8 site that contains private data, from development to launch and after.
The information below comes from various sources, including the security recommendations on Drupal.org, articles from Drupal Planet that discuss security, a Drupal security class I took with Gregg Knaddison and his 2009 book Cracking Drupal, a review a numerous internal Lullabot documents regarding security, and other sources. This list was reviewed by Lullabot's security team. That said, for more comprehensive content and considerations, I recommend learning more about securing your site on Drupal.org and other security sources.
- Configure all servers and environments to use HTTPS.
- Install the site following the Drupal guidelines to secure file permissions and ownership (using the
fix-permissions.shincluded with the guidelines is a quick way to do this).
- Hide important core files that may allow attackers to identify the installed version (the point release) of Drupal, install new sites, update existing sites, or perform maintenance tasks. For example, when using Apache add something like this to your .htaccess configuration file:
<FilesMatch "(MAINTAINERS|INSTALL|INSTALL.mysql|CHANGELOG).txt"> Order deny,allow deny from all Allow from 127.0.0.1 <-- your domain goes here </FilesMatch> <FilesMatch "(authorize|cron|install|update).php"> Order deny,allow deny from all Allow from 127.0.0.1 <-- your domain goes here </FilesMatch>
- Configure a hard-to-guess table name prefix (e.g.
5d3R_) in the
$databasesarray to deter SQL injections (this suggestion comes from KeyCDN).
- Check that
$update_free_access = FALSE;to further prevent using the
- Configure trusted host patterns (e.g.
$settings['trusted_host_patterns'] = ['^www\.example\.com$'];).
- In each environment (development, staging, and production) configure a private files directory located outside of the web root.
- Configure a hard-to-guess table name prefix (e.g.
- If you are running MariaDB 10.1.4 or greater with a XtraDB or InnoDB storage engine on your own hardware (as opposed to a hosting provider such as Linode or AWS), enable data-at-rest encryption.
- Establish a regular process for code, files, and database off site backup using an encryption tool such as GPG or a service such as NodeSquirrel.
- If a VPN is available, restrict access to the administrative parts of the site to only local network/VPN users by blocking access to any pages with “admin” in the URL.
- Note that these recommendations also apply to Docker containers, which often run everything as root out of the box. Please be aware that the Docker Community -- not the Drupal Community or the Drupal Security Team -- maintains the official Docker images for Drupal.
- Before launching the site, calibrate security expectations and effort. Consider questions such as, who are the past attackers? Who are the most vulnerable users of the site? Where are the weaknesses in the system design that are "by design"? What are the costs of a breach? This discussion might be a good project kickoff topic.
- Establish a policy to stay up-to-date with Drupal security advisories and announcements. Subscribe via RSS or email, follow @drupalsecurity on Twitter, or create an IRC bot that automatically posts security updates. Use whatever method works best for your team.
- Create a process for keeping modules up to date, how and when security updates are applied, and considers the security risk level. Drupal security advisories are based on the NIST Common Misuse Scoring System (NISTIR 7864), so advisories marked "Confidentiality impact" (CI) are especially crucial for sites with private and confidential data.
- Establish a process for handling zero-day vulnerabilities.
- Review content types to ensure that all sensitive data, such as user photos and other sensitive files, are uploaded as private files.
- Implement one or more of the Drupal modules for password management. The United States National Institute of Standards and Technology (NIST) offers detailed guidelines about passwords. Here are some policies that are easy to implement using submodules of the Password Policy module:
- At least 8 characters (Password Character Length Policy module)
- Maximum of 2 consecutive identical characters (Password Consecutive Characters Policy module)
- Password cannot match username (Password Username Policy)
- Password cannot be reused (Password Policy History)
- Consider having your organization standardize on a password manager and implement training for all employees.
- Consider using the Two-Factor Authentication (TFA) module.
- Change the admin username to something other than admin.
- Enable the Login Security module, which detects password-guessing and brute-force attacks performed against the Drupal login form.
- Enable Security Review module, run the Security Review checklist, and make sure all tests pass. Disable this module before site launch, but use this module to perform security reviews each time core or contributed modules are updated.
- Carefully review Drupal user permissions and lock down restricted areas of the site.
- Perform a thorough and recurring analysis of your site using online tools such as Qualys SSL Server Test, Sucuri SiteCheck scanner, Unmask Parasites, and securityheaders.com.
- Carefully review contributed modules to ensure they contain secure code. Prioritize stable releases of modules that are covered by Drupal's security advisory policy.
- For custom modules, follow advice for writing secure code.
- Follow guidelines to preserve user input and ensure that all output is sanitized.
- Build forms using Drupal's Form API to help protect against cross-site request forgeries (CSRF).
- Check code integrity before each deployment with the Coder module.
- Use the drush tools provided by Database Sanitize to sanitize database data for local development.