Drupal Security

Drupal Security Audits: What to look for

Security audits in Drupal are not a trivial thing. This is how we do it.

Photo of Salvador Molina Moreno
Tue, 2016-03-22 13:59By salva

Site audits are one of the services that some of our clients have requested from us in the past. While a site audit might be done with a specific objective in mind, there's always a common reason: find, understand, and fix any potential holes or problems that could cause a service outage on the site, or on the server where it is hosted. In some cases, that's the only reason, whereas in other cases the outcome of the audit will inform a more important decision, such as a platform or server move, or a site rebuild, to name a few.

Depending on the goal of an audit, the things to look at on the site might change a bit: is it a performance audit, a security one, or a general review to check the overall status of the site and the feasibility of keep evolving it in an efficient way? This post covers the details concerning security audits in particular, although some of the practices mentioned here do not belong exclusively to the realm of security, and will be equally needed in other audits. Let's get started.

General aspects

There are some things that an audit should always cover, as they give a good overview of the site and how well it's been looked after. Some of these aspects are:

  • General codebase observations: Get an overview of the structure and organisation of modules and custom php scripts (if any). In big projects, where people come and go and different developers get to work on the code, it's not uncommon to see a big mess in custom code, structured without consistent patterns or styleguides. This might not affect security directly, but it might be a sign that not much care has been put into how things are done, and it will surely impact maintenance.
  • General code inspection: Performed through an IDE or automated tools, to find extensive uses of bad practices in code. Again, this might not necessarily surface any potential security holes, but depending on the tools used, there are cases in which it could actually do so. A good tool for a general review of Drupal modules is the Coder module, which can be tuned to look only for problems of a specific nature (e.g: only check Drupal standards).
  • Site Audit Script: The Site Audit module is worth a look as well. While it's not the most feature-complete audit tool, it provides useful info about certain areas of a Drupal site, and includes some security checks too.
  • Watch out for patched modules: The Hacked! module can help you to easily identify which contributed modules have been altered by developers after the official version was added to the codebase.  It compares the installed version with the official one available in www.drupal.org, to highlight the differences. If the development team have behaved well, all these patches will be documented in some way in the codebase, so make sure you consider them in more specific audits, in particular for security.

Finding the security holes

Drupal core is great when it comes to security, and it also encourages module developers to follow good practices when contributing to the community, by providing clear guidelines about how to write secure code. However, considering the low entry barrier of the platform for anyone who has some basic PHP skills, it's not hard to find projects in which some of the standard APIs and guideliness are either overlooked, or bypassed entirely. This opens possible security holes in the system.

Being a CMS, the possible security holes of a Drupal site may not lay only in the codebase, but also in how the different modules are configured, often in a too-permissive fashion. Enabling PHP Filter to allow PHP execution from the UI, or a bad configuration of input (text) formats, are just a couple examples of how a bad configuration could be used to breach into the site. You can find more details about this in this page of the Administration & Security Guide.

In this article, I'd like to focus a bit more in the possible issues that can be generated at the codebase level. The next list covers the most common vulnerabilities that should be looked for when auditing a Drupal project, and some other aspects to consider. These checks are normally for the custom code. Some details are given next to each vulnerability type, with the common functions or elements that can be used to exploit the vulnerability, or where it might be introduced:

  • SQL Injection: Make sure no $_GET data is used without proper sanitisation, specially if it's going to be used in queries to the database. The term is a classic, I know, and it's been used and abused all over the web for a lot of years, but not without cause: it's been less than two years since I came across a vulnerability of this type (don't get excited, you won't find any name and shame in this post). 

    • Check as well for usage of drupal_get_query_parameters(). If not treated safely, data received from there can be as dangerous as $_GET.

  • Remote code execution: Make sure $_POST data is being used safely.  Not usually an issue if Drupal Form API is used. While not encouraged, it's possible for developers to use $_POST or $form_state['input'] to retrieve user-submitted data. So, when searching for places where this kind of data is used in code, make sure those variable names are included in the search.

    • Pay also attention to custom data stored in the database that is later used for custom logic, but having being previously retrieved through a custom form.

    • Some functions can be used to exploit vulnerabilities with malicious data captured through any of the methods described. Most of these functions are not too common for small websites, but they can be very dangerous if not used with care, so it's always worth looking for any usages of these in code, and in case you see any of them, ensure they're used safely:

      • eval

      • preg_replace

      • create_function

      • include_once

      • require_once

      • system

      • exec

      • shell_exec

      • pcntl_exec

  • XSS / Persistent XSS: Another classic. Check that all user input is sanitised before being output as HTML. See Handle text in a secure fashion:

    • General checks. Make sure these functions or statements are used according to the documentation, and with data sanitised where relevant:

      • print.

      • echo.

      • l().

      • t().

    • Custom blocks:

      • Make sure anything contained in blocks content is sanitised, since these contents are output "as is".

    • Other possibly dangerous Drupal elements:

      These elements are not dangerous as such, but they're used to display HTML contents. The general idea here is: sanitise data before displaying it!

      • theme(‘placeholder’).

      • drupal_set_title().

      • theme(‘username’).

      • Custom forms.

      • Form API #title and #description

      • Form API #markup types.

      • Review usages of rich text fields in code, and make sure they're always displayed using their appropriate text format.

    • Treatment of incoming URL data in usage of HTML attributes. Arguments that might be used in HTML attributes could be encoded in a way that malforms the HTML to ultimately inject Javascript.

    • Views fields without sanitising (e.g: using the "raw” contents from a views template).

  • Privilege escalation:

    • Do all custom hook_menu functions have access arguments declared?

    • Do all custom queries use the node_access tag where required?

    • Are permissions respected when displaying entities retrieved via EntityFieldQuery?

  • CSRF: Make sure all custom forms use Drupal's FAPI or confirmation forms / tokens.

  • General configuration:

    These are some of the most common checks to go through when reviewing the site configuration:

    • HTTPS configured correctly.

    • PHP filter is disabled.

    • Access to text formats.

    • Private files directory is in a secure location outside of webroot.

    • Execution of PHP files in subfolders disabled.

  • Everything else covered in the Writing secure code page of the Drupal developer handbook.

  • Anything listed in the OWASP Top 10 should be always present in a security audit.


Some of the points listed there are rather uncommon to see these days. However, no matter how unlikely they are, a security vulnerability is always a risk, so as good developers is our duty to, at least, try our best to make sure we follow good practices and don't create holes in the system, or fix them if we find any.

Once in the auditor role, there are tools to automate the search for some of the possible issues in code. One example is the Security Review module for Drupal, which makes some checks on a given site (none on the codebase itself) and generates a report highlighting the areas where the configuration should be changed. Taking it a step further, the Paranoia module will automatically make some changes to your site, disabling certain sections or features that could make it insecure.

Security is not a setting, it's a process, and even experts (except Code Enigma sysadmins) make mistakes. The worst mistake one can make about a site is taking its security for granted.