Upgrade Your Drupal Skills

We trained 1,000+ Drupal Developers over the last decade.

See Advanced Courses NAH, I know Enough
Sep 09 2021
Sep 09

In the previous parts, we focused on Drupal configuration and the overview of modules and libraries. In the third part of the series on conducting a security audit, we'll focus on the overview of custom modules and themes. We'll perform an audit of the project repository, identify and analyze the elements worth paying attention to during the auditing process.

Overview of custom Drupal themes and modules

In custom Drupal themes and modules, attack vectors are most likely to appear. There's code there that isn't being widely used, unlike the code for contrib modules and themes. Therefore, it's not so well-tested in terms of security. In this article, I'll discuss a basic checklist used for auditing custom Drupal code. This list can be used as the basis for an audit of custom modules and themes.


We’ll start with the analysis of the parameters received from the user. Let's check out what is their type and how are they filtered. Drupal allows for using parameters in routings. These are dynamic values, incorrect processing of which may create attack vectors. If a query is created on the basis of a parameter and not filtered, this may cause a vector for SQL Injection attack, for example.

Next, we should look at the routing access configuration, specifically – the permissions that the user must have to get access. When declaring the routing, we need to define the requirements that the user must meet to gain access to the routing. We have to analyze the required permissions for every routing specified in our custom Drupal code and consider whether their level is appropriate. Specifying too low or incorrect level of required permissions will result in users having access to pages that they shouldn’t have access to. These can be both the pages listing the articles on your page and the pages listing all users along with all the data assigned to a given account. For this reason, the permissions audit is so important.


First, we'll analyze the correctness of the element types and check out if the correct type for a given field has been used. During the analysis of the types of fields used in the form, we may come across a field whose name and description suggest that it should be filled out with data of a specific type. However, the field's definition may allow the field to be filled out with other types of data. We should make sure that the definition of the type of elements corresponds with their purpose.

The next step will be to analyze the used methods of validating the field values in the form. Drupal allows for defining custom methods that validate the correctness of the entered data. We should test the correctness of the custom validation methods and make sure that only the valid data passes the validation.

The last thing will be to verify the presence and correct use of Form API provided by Drupal. We should analyze the way of using Form API, preferably using the documentation, and make sure that the forms are being created as directed.

The documentation specifies:

  • the cases where the use of a given field type is correct,
  • how to create the methods of validation,
  • how to use hook_form_alter,
  • how to create forms to be intuitive for the user.

SQL queries

Let's start with verifying the presence and correct use of the Database API provided by Drupal. It's equipped with methods providing security against attacks on the database. The correct use of API largely protects against attacks. We should particularly pay attention to whether input data filtering methods are used in the SQL queries. Drupal recommends using placeholders if there's a need to use input data, e.g., from a variable the value of which has been specified by the user in the form. Here's an example:

$foo = $this->getFormData(); $query = \Database::getConnection()->query(‘SELECT foo FROM {bar} b WHERE b.name = ‘ . $foo[‘name’]);

In the code above, we can see that the value 'name' from the $foo array is being assigned to the query without filtering. In such cases, I recommend using placeholders.

$foo = $this->getFormData(); $query = \Database::getConnection()->query(‘SELECT foo FROM {bar} b WHERE b.name = :name’, [‘:name’ => $foo[‘name’]]);

By creating queries in this way, we subject the variable $foo ['name'] to filtering, which will protect the query against SQL Injection attacks.

Filtering mechanisms

This means verifying the presence and correctness of the filtering data received from the user. We need to check that only TWIG is being used to render the variables in the templates, which by default filters the content of the variables and makes sure that they're safe. In the case of working with variables that are then used in translatable strings, we need to make sure that those variables are substituted for the appropriate placeholders. The plain text coming from the user should be filtered using the Html::escape() method if the user shouldn't be able to provide HTML tags in the text and the Xss::filterAdmin() function if they should be able to do so. If the user provides links, they should also be filtered.

Used for this purpose are the functions UrlHelper::stripDangerousProtocols() and UrlHelper::filterBadProtocol(). Filtering mechanisms are also applicable on the client's side. To clean up text in JavaScript, we should use the Drupal.checkPlain() function.

Sensitive data

We should check whether the code doesn't contain credentials or API keys. In some cases, we may come across the credentials left in the code of custom modules. Identifying them doesn't require much work.

Repository review

It's worth taking a look at the repository to search for sensitive information that may be stored in the files. The first step is to analyse the settings.php file and ensure that there are no credentials in it that would provide access to the database or other Drupal website components. Next, let's go over the environment variables' files and make sure there aren't any credentials in them. The credentials required by the environment shouldn't be part of the repository.

The next step is to check if there are no deeply hidden confidential files, for example – with SSL private keys or database copies or dumps. Sometimes the files that should never be in the repository get there by mistake. Some of them are, for example, database dumps or private keys. Identifying and removing them is recommended.

Analysis of the Drupal code – summary

In the third part of the series on performing a Drupal security audit, we've learned the ways of checking the code of custom modules and themes, we've audited the project's repository in order to make sure that no sensitive data was publicly available, and we've analyzed the elements that are worth paying attention to during the audit process.

Applying the tips I've posted in this article will make your application more secure. A code audit is a key element leading to better page security. It requires more time and knowledge than the update we covered in the first part and the correct configuration of Drupal we covered in the second part of the series, but the benefits of doing it are much more valuable than the time spent on it.

In the next part of this series of articles, we'll learn about external tools for automating the auditing process. It's the next step performed in a comprehensive security audit. Do you need help in performing such a task? Our Drupal support team has extensive experience in conducting audits.

Aug 10 2021
Aug 10

In the first part of the series on Drupal security audits, we described how to review modules and libraries. However, modules and dependencies will be useless if any user will be able to see our custom routing where we display all the client information. Therefore, in this article we'll look at the configuration of our website. Correct configuration is one of the key elements affecting security.

Checking the Drupal configuration

For this part, our list will include checking the role permissions, access to the Drupal views and routings, among other things. We'll also verify the correctness of the text formats configuration and perform other checks to find the largest number of potential vectors of attack on our application.

Role permissions audit

By going to /admin/people/roles, we’ll see the list of all available roles.

The list of all available roles on our Drupal website, visible on the Roles page


In the list on the right (the OPERATIONS column), after clicking we can select the edit permissions option, which will redirect us to the page /admin/people/permissions/[machine_name_of_the_role] (example for the Anonymous role: /admin/people/permissions/anonymous). After going to the permissions edit, Drupal will list all the possible permissions that have been granted for the selected role.

After going to the permissions edit, we can see all permissions assigned to a particular role on a Drupal website


To verify the permissions, we should first consider what task is assigned to the role. We need to ask ourselves whether role X should have permission for action Y, for example: should the content editor role be able to edit all views? If the answer is no, the permissions should be restricted.

Full knowledge of the project is required for a permissions audit. If we find a permission that we believe a given role shouldn't have, we should only inform in the audit report about the possibility of the role having optional permissions. We'll provide more information on how to create a good report in one of the next articles in the Drupal security audit series.

View permissions audit

After auditing the roles, it's time to take a look at the views. They're all listed under /admin/structure/views.

A list of views available for a particular user, located on the Views page in Drupal


Our first task, in this case, will be to enter into the edit of each view that provides routing. We need to find the PAGE SETTINGS section, and more specifically – the Access option, which should only intentionally be set to "Unrestricted".

The Access option in the Page Settings section which is worth checking at the beginning of the views permissions audit


As is the case with the roles, when auditing the view permissions, we should ask ourselves: what restrictions should be put on the X view? If the view should be accessible to everyone, it's good practice to use a restriction which requires having permission to access the published content. If any of the views have no restrictions or we find them to be too moderate, we should inform about it in the report.

Audit of the routing.yml files in custom modules

When it comes to the routings created in custom modules, the audit looks similar. We should review every *.routing.yml file to ensure that every routing has the appropriate level of security. Here is an example of a new routing declaration

A new routing declaration can look this way


In this case, every user with the access content permission is permitted to access the /machine_name/transliterate page. It's also a good practice in this case to define a minimum access level for every access content routing.

Text formats audit

The path /admin/config/content/formats contains all the text formats available on the page. In this case, the audit will consist of checking, for example, whether it isn’t possible to insert JavaScript code using a given text format or whether it isn't possible to link an image that will be downloaded from another page. It's also important for the list of possible file extensions not to allow uploading files with unsafe extensions if it isn't necessary. Of course, we report the configuration errors – the risk level depends on the type of error.

Error logging audit

There is the Error messages to display configuration option on the /admin/config/development/logging page. It's used to set the error display level. This option should be set to None on the production page. If this option is set to a variant other than None in the production environment, we report it as a low-level threat.

The Error messages to display option in Drupal should be set to None


Basic login audit

There are two ways for the login panel to inform if the user trying to log in provided incorrect data. It may give a brief answer such as "data is incorrect", or give one piece of information when the login is incorrect, and another when the password is incorrect. In the last case, we're dealing with a vector for a brute force attack. The attacker may first storm the logins and then the passwords – thus gaining access to the user accounts.

Another aspect worth checking out is the password policy. It's a controversial topic, since some propose to force a password change periodically, and others say that the password should contain at least one uppercase character, one lowercase character, one digit and one special character. Some people combine both these rules, and users end up creating passwords like July2021! which meet all the requirements. My personal recommendation in this case rules out the necessity to change the password from time to time. Determining the complexity of the password is recommended, but the most important thing is its length - the longer the password is, the more time it'll take to crack it. The password policy is an issue that depends on the type of project and must be analyzed individually. In the case of a weak password policy, you should report it as a threat with a level depending on how bad the policy is.

Forms audit

The forms should be protected against spam. They should be created using the Drupal API where possible. Check if the forms are protected against spam and if their validation doesn't allow entering incorrect or dangerous data. If you find an incorrectness in the form's configuration, you should be reported – the risk level depends on the situation. There'll be a different level of risk for a potential SQLi, and for the possibility of entering incorrect data – for example in the select list.

Additional recommendations

There are Drupal modules that increase the security of our application. One such module is Security Kit. Thanks to it you'll reduce the likelihood of using the website's security gaps. This module offers Anti-XSS, Anti-CSRF, Anti-ClickJacking, and other security measures. We recommend reading the linked post and considering the installation.

Security Review is a module that can help with a Drupal security audit. It uses automated security tests that help with performing the audit.

This module:

  • checks the file permissions,
  • performs a file formats audit,
  • performs an audit of the options responsible for reporting errors,
  • performs an options audit, in which we determine which file extensions can be uploaded (e.g. to be downloaded in a blog post),
  • monitors database errors in order to detect a potential attack,
  • monitors the login panel for the same purpose,
  • checks the configuration of the trusted hosts file,
  • checks the view permissions.

Security Review is recommended as it can speed up the process of auditing the page.

Drupal configuration checked - what's next?

In this part of the series on performing a Drupal security audit, we've learned the ways of checking the Drupal configuration. We are familiar with the configuration options that can open attack vectors and we know what the recommendations are for closing these vectors.

Acquiring the knowledge provided in this post has allowed you to better understand that a correct Drupal configuration is as important as keeping it up-to-date. A configuration audit is another of the activities that we perform during a security audit - our Drupal support team recommends a comprehensive configuration check during a security audit.

In the next part of this series of articles, we'll deal with the code and learn about the basic ways to audit it. We'll present the ways of analyzing modules and themes. We'll take a look at what's in the repository. Are there any passwords, keys in it? Or maybe the entire database dump?

Jul 22 2021
Jul 22

A security audit is the process of identifying security threats that can lead to unauthorised access to content, data leaks, bypassing the security, and other dangers. In the first part of the series on conducting a security audit, we'll focus on the overview of the Drupal module versions that we use at Droptica for this purpose, as well as on PHP and JavaScript libraries.

Drupal security audit

At Droptica, we make every effort to ensure that the solutions we provide are as safe as possible. We use the tools provided by the Drupal community, such as the Security Review module, to optimize the process of detecting the most popular security errors. We also use the Security Kit to make the project we're working on more resistant to attacks. You can learn more about the functionality of these modules in the linked posts, and the information on their operation will be useful in the following parts, in which we'll talk about the Drupal configuration review and code analysis.

Checking the versions of the installed Drupal modules

Updating modules and libraries is the simplest activity that we can perform to improve the security of our application. Drupal provides a view listing all the modules, which additionally indicates whether a given module is up-to-date, and if it isn’t – whether the update contains security fixes.

To check if the modules are up-to-date, go to /admin/modules/update

Checking the versions of Drupal modules as part of security audit

In the screenshot above, you can see that some of the modules need updating. Of course, in such cases we always recommend that you update all possible modules. If any of the modules contain a security fix, the update is required to ensure a high level of security for the application.

In the case of Drupal, the information about whether a given module has a security flaw is made available to the public when the author of the module releases its patched version. Module authors usually try to hide which code has been changed to patch a security flaw, but this always means that the attacker just needs more time to find a way to cause the bug and exploit it. Time is important, so you should keep track of security updates regularly, not only during a Drupal security audit. As we mentioned earlier, this is one of the simplest steps we can take to ensure a higher level of security for our application.

Patches review

When updating the Drupal modules, you should also check if a patch has been applied to a given module. If so, we proceed as follows:

  1. We check whether the patch was created by the community and if it concerns a specific issue on drupal.org. If so, we look for the issue that the patch is from. It's possible that the patch has been applied to one of the newer versions of the module. In such a case, we recommend updating the module and removing the patch with the information that the code that fixes the bug or adds a given functionality has been applied to the official, newer version of the module. If the patch hasn’t yet been applied to the newer version of the module, we still recommend updating and testing if the latest version of the patch serves its purpose.
  2. If the patch wasn’t created by the Drupal community, but is the result of working on the project, we still recommend updating the module. In this case, however, ensuring the correct operation of the patch lies with the people responsible for the custom code of the project. After updating, you should check whether the patch works as intended. If not, we recommend introducing appropriate fixes to the patch which will ensure its correct operation on the latest version of the module.

PHP libraries review

The next step will be reviewing the used PHP libraries. To list them, we can use the composer show command or the local-php-security-checker package. We recommend the latter solution because it significantly speeds up the process.

Result of the composer show command during the review of the used PHP libraries

Result of the composer show command.

If you choose to install the local-php-security-checker package, follow the guidelines in the README.md file.

Result of the scan using local-php-security-checker during a Drupal security audit

Result of the scan using local-php-security-checker.

There's also the little-known Drupal Composer Security Checker module that uses the security-checker package. Currently, this module doesn't fulfill its task and the security-checker package itself isn't actively developed (since January 2021), therefore we'll focus on the local-php-security-checker package itself. If you find a security risk, our recommendation will be to update the library, of course – as in any case. An audit of the PHP libraries should be carried out regularly, the same as in the case of the Drupal modules.

JavaScript libraries review

The next step will be to check if the used JavaScript libraries are up-to-date and if they contain security fixes. To do this, you should review the library directory and the used package.json files.

In the case of the library directory, you need to check the version manually. In the case of package.json, we use the npm-audit command.

Result of the npm-audit command checking the package.json during the JavaScript libraries review

Result of the npm-audit command

The npm-audit command will list all known vulnerabilities, determine the threat level, package, dependencies, package path, and show a link with information about the vulnerability.

The npm-audit command shows all vulnerabilities in the JavaScript libraries

If you find a vulnerability, as always we recommend the update. JS library scans should be performed routinely, more often than a comprehensive security audit.

Improving the Drupal security - further steps

In this part of the Drupal security audit cycle, we've learned how to check whether the used versions of the modules and libraries are up-to-date and don't contain known security bugs. We also understand how to proceed if there is a patch available for a module – both when the patch comes from the Drupal community and when it was prepared by the developer working on the application.

Acquiring the knowledge provided in this post is the easiest way to improve the security of your application. Checking the versions of the used solutions is the first step that we perform during a security audit - our Drupal support team recommends periodic checking for updates. In the event that an update containing security fixes is released, we recommend that you perform an update as soon as possible.

In the next part of this series of articles, we'll get to learn more about the Drupal configuration aimed at increasing the security of our application. We'll also learn how to reduce the number of attack vectors and we'll find out more about the modules that'll help us with this.

Dec 18 2020
Dec 18

Security Kit is a module that helps with eliminating the likelihood of exploiting security vulnerabilities on your website. Thanks to a multitude of features, such as Anti-XSS, Anti-CSRF, Anti-ClickJacking you can get yourself a peace of mind and comprehensively define a security policy for your website.

At our Drupal agency, we value the security of our customers' websites and make every effort to ensure that the solutions we provide are as bug-free as possible, which is why our development team uses tools to achieve this goal optimally. We use modules provided by Drupal's outstanding community, which facilitate this process. For example, when auditing an acquired project, we use the Hacked module, and while implementing the solutions required by your projects, we are always taking advantage of the Security Review. Today I would like to introduce you to another module that will help you secure your website – Security Kit (SecKit).


The first version of the module was released on 26 March 2011. The latest update was released on 28 August 2020. The module is now considered to be feature-complete by its developers – new features are currently not being developed, and the updates focus solely on patches.

Module popularity

The module is used by about 56,000 websites, including 25,000 based on Drupal 7 and 26,000 on Drupal 8.


You can find detailed popularity statistics here.

Module developers

The module was developed by p0deje. It is currently maintained by Acquia and Catalyst IT. The vast majority of commits were provided by p0deje (141), jweowu (26) and mcdruid (24).

As of now, the module has four maintainers: mcdruid, jweowu, badjava, and p0deje.

What does it do?

Security Kit combined with Drupal offers additional options and features that improve security, reducing the risk of exploiting vulnerabilities on your website, by adding Anti-XSS, Anti-CSRF, Anti-ClickJacking, HSTS and CORS implementations. The module enables you to define a multitude of security policies – you can find a description of each configuration option in the "Settings" section.

Let's take a closer look at what it can do for you!


Features that help lower the possibility of exploiting cross-site scripting (XSS) vulnerabilities on your website. XSS is a type of website vulnerability that allows the attacker to execute any JavaScript code directly on the end device. XSS may result in leaking data, such as login and password, credit card details, user account information and much more. There are a number of types of XSS attacks; if you want to learn more, you can start exploring them here.


Cross-Site Request Forgery (CSRF) is an attack type that allows the attacker to trick end users into performing specific actions on a website. A CSRF attack may, for example, result in the end-user losing their funds, changing their email address linked to the website, changing their password and any other action which the user can perform.


Clickjacking is an exploit which enables an attacker to trick end users by displaying a concealed xframe, which the user can unwittingly click to run a given action on another website. Attacks of this kind can be used, for example, to farm likes on the attacker's Facebook page. The latter type of attack now even has its own name – Likejacking.


HTTP Strict Transport Security (HSTS) security policy that minimises the risk of man-in-the-middle attacks, which entail modifying a request before it even reaches the server.


Cross-origin resource sharing (CORS) is a mechanism that allows you to specify a list of trusted domains from which the user can download resources on your website.


The module does not require any external libraries to work correctly. Security Kit can be installed in a standard manner, but – as always – we do recommend using composer:

composer requires drupal/seckit


Cross-site scripting

This section contains settings that boost your website's security performance in terms of XSS-type attacks.


Content security policy

Security policy enables you to identify trusted content sources. Serving content from untrusted sources may lead to security issues, such as data leakage and malware distribution. You can read more about this here.

Send HTTP response header

If you select this option, the CSP policy is enabled.

Enable Upgrade Insecure Requests

If you select this option, all HTTP requests are redirected automatically to HTTPS.

Report only

If this option is selected, all the cases of content security policy breaches will not be blocked, only logged.


This option defines a security policy for all content on the website, such as scripts, styles, images, media, frames, etc. If you do not specify a separate policy for a given content type, the CSP will use the policy specified in this field.

This allows you to provide trusted sources for particular content types, such as script, object, style, img, media, frame, font.


Path used for reporting requests violating your CSP policy.


If you want your CSP policy to be saved in one file, here you can specify a path. If this field is filled, the settings per content type are omitted.

X-XSS-Protection header

Each browser has its own internal safeguards against XSS. X-XSS-Protection header enables you to disable the default anti-XSS protection built into your browser, run the safeguards along with modifying unsecured content to protect users from XSS attacks or run protection mechanisms that will block all dangerous content. If you would like to learn more about the header, take a look here.


This section contains settings that protect your website from cross-site request forgery attacks.


HTTP Origin

If you select this option, you enable the validation of the HTTP request source, thus enabling CORS protection.

Allow request from

A list of accepted requests.


This section contains settings that improve your website's security in response to ClickJacking attacks.


X Frame options

X-Frame-Options configuration

  • Disabled - disables the X-Frame-Options header.
  • SAMEORIGIN – makes it so that the page can display xframes only served from the same domain.
  • DENY – locks all xframes.
  • ALLOW-FROM – allows you to specify a list of domains with xframes enabled.

You can read more about the XFrame header here.

You can also find the header specification here.

JavaScript-based protection

Enables anti-clickjacking protection using JavaScript. This solution will not work for users who block JavaScript using browser plug-ins such as NoScript.

Custom text for disabled JavaScript message

Enables you to provide a message that will be shown to users blocking JavaScript on your website, as well as users whose browsers do not support JavaScript.


A section containing settings improving SSL/TLS security.


HTTP Strict Transport Security

Enables the Strict-Transport-Security (HSTS) header – enabling this option will increase security by reducing the risk of man-in-the-middle attacks such as SSLStrip. You can read up on HSTS here.


Defines the max-age value of the HSTS header. Max age is the number of seconds for which the website is treated as HSTS-enabled by the end-user.

Include Subdomains

Enables HSTS for all subdomains – by default, the HSTS header is only sent from the main domain.


Most popular browsers have HSTS preload lists with sites that are defined as HTTPS-enabled. If you want your domain to be added to the HSTS Preload list, you need to check this option.

Expect CT

Expect-CT header configuration options allow you to enable reporting and enforcing the Certificate Transparency policy. The Certificate Transparency Policy defines the sources, delivery and signing mechanisms of certificates when using TLS connections. You can read more about this here.

Expect CT


Enables Expect-CT header.


Defines the max-age attribute for the Expect-CT header. Max age is the number of seconds after receiving the Expect-CT header during which the user's browser considers your website to be compliant with Expect-CT header.


URI for reporting Expect-CT errors. Errors are reported if the user does not receive correct CT information.


The optional header parameter specifies whether the user should enforce the Certificate Transparency policy or only report in case of an error.

Feature policy

Configuration options for the Feature-Policy header, which determine the API configuration and behaviour, as well as features provided by the browser, for example, it allows you to limit the APIs used for interacting with user's camera or microphone, as well as change the default behaviour of the autoplay attribute on mobile devices. You can find out more about this here.

Feature policy

Feature policy

Checking this option enables the Feature-Policy header.


Defines the Feature-Policy header policy.


Configuration of the remaining module options that do not belong to any particular category.



Enables the From-Origin-Response header. This option specifies websites on which the resources from your website can be embedded. You can find out more about this in the header specification.

Allow loading content to

Enables you to specify a list of domains, where your content can be embedded (if From-Origin is used).


Enables the Referrer-Policy response header.

Select policy

Defines the policy for the Referrer-Policy header. Information about this header and available options can be found in the specification.

Disable autocomplete on login and registration form

Checking this option will disable the ability of the browser to fill in the login and registration forms automatically.


The presented module enables you to configure many options that increase the security level and performance of your website. It also provides you with a number of ways that allow you to define security policies, while the added security mechanisms help protect your website against popular attacks. Our Drupal developers recommends deploying the SecurityKit module.

Dec 09 2020
Dec 09

When working on a project, there are many ways to increase the security of a website. One of them is the use of automated security tests that assist developers in eliminating as many security bugs as possible.

At Droptica, our Drupal developers focus on delivering the safest solutions. The Drupal CMS itself helps us in this, as it is safer than other CMSs. Thanks to the huge community focused on opensource projects, one of which is Drupal, clients, on the one hand, receive effective solutions, and on the other hand, can be sure about their security. At this point, it is worth to mention a special team dedicated to this issue, which is the Drupal Security Team.

In this text, I would like to introduce you to the operation of one of the tools to increase the security of your website – the Security Review module.


The module was released on 4 November 2009, and the most recent update was introduced on 4 October 2019. The module has a version for Drupal 7 and 8

The module’s popularity

According to drupal.org, 30,000 websites are using the module, 28,000 of which are Drupal 7 and 2,000 are Drupal 8.

Module’s creators

The module’s creator is the user named greggles. The module is supported and developed by the Acquia, CARD.com and Google Summer of Code organisations. The most commits were provided by the users coltrane (111), banviktor (58) and greggles (8).

What is the module used for?

The module performs an automatic website audit detailing many attack vectors that can lead to security errors. Here is the list of some of them:

File permissions

Saving files to the server’s root directory is dangerous and may lead to a remote code execution error. An attacker can use this vulnerability to take control of a website. More information on the correct configuration of permissions can be found at this link.

The list of tags accepted by the text formats available in the CMS

Some HTML tags are considered unsafe. This means that they may allow an attacker to take control of a website. Drupal has an HTML filtering engine that removes malicious tags - this test checks if the filtering is set up correctly.

Error reporting

Drupal may disclose information about errors to unauthorized persons. An attacker can use this information to refine an attack or find more vectors.

Unsafe file extensions

Some extensions are considered unsafe. This means that they can cause security errors such as remote code execution. This allows an attacker to take control of a website, and Security Review checks whether Drupal enables the transfer of files with unsafe extensions.

Database errors

Many database errors triggered by a single IP address are a sign that someone is trying to make a SQL injection attack. The module informs if multiple database errors were triggered from the same IP address.

Login panel brute force

Multiple failed login attempts are an indication that someone is trying to get into another user’s account. You are being informed about it.

Trusted hosts (HTTP host header attack)

Correct configuration of Trusted Host protects against HTTP host header attack, a detailed description of the settings is available at this link.

Views access

Security Review recommends that access to Drupal views should have at least minimal ‘access content’ control. This test checks whether the views have at least a minimum level of access control.

Security Review does not introduce any security fixes but only suggests where vectors of attack may be present. These are suggested changes that need to be analysed by a specialist.


The module installation is standard, but we suggest using the Composer:

composer require drupal/security_review


Under the address


you can configure the module by selecting roles that are not trusted. Security Review uses this as a basis for checking whether the users with not trusted roles have permissions to the functionalities that may cause security errors. You can also choose which items from the checklist you want to omit and choose the method of checking the trusted hosts.


Role configuration

The module provides two types of permissions: ‘access security review list’, ‘run security checks’. First, you need to configure the trusted roles that will be able to read reports and run the scan. In order to do this, go to


and configure the permissions for selected roles:


Module’s use

The module has already been configured. To run an audit, just go to


and click “Run checklist”, and Security Review will conduct the audit. You can also use the drush command:

drush secrev


Every test has a summary that you can see by clicking on the “details”. An example for “Errors are written to the screen”:


Moving on to the error logging settings, you can see that Drupal shows all the information, including the backtrace:


In the case of a production version of a website, set this option to “none” in order to minimise the risk of disclosing information that could help an attacker to hijack the website.

Similar information is provided for each of the security errors detected during the audit. All items should be reviewed manually, and appropriate changes should be made – if required.

Alternative modules

The Paranoia module identifies all the areas where a user may be able to trigger the custom PHP code and tries to block them. This reduces the possibility of a remote code execution error occurring. In addition, the module protects the main admin account (account with id 1), preventing its editing and blocking the possibility of uninstalling itself using the standard way (to uninstall the paranoia module, you need to edit the database manually). All the functionalities provided by the Paranoia module are intended to increase the security of a website.


The Security Review module is an extremely important and useful tool. Thanks to the information collected by the module, you gain invaluable knowledge of what should be done in order to improve the security of your website. After analysing the results, you can eliminate some of the attack vectors. Our team recommends using this module when creating a website.

Dec 02 2020
Dec 02

During a website audit, it is possible to detect whether changes have been made to the Drupal core, modules and contrib themes. How to do that? The most effective way to do this is to use the Hacked! module.


The module was released on 8 October 2009, and the last modification was introduced on 13 February 2020. Hacked! has a version for both Drupal 7 and 8.

Module's popularity

Drupal.org reports that the module is being used by approximately 16,000 pages of which 15,100 are Drupal 7 pages and 900 are Drupal 8 pages. In the case of the Hacked! however, this is not very reliable information, as it is a module that should only be used in development environments for a short time and should be uninstalled after the work is done. So, one could rather say that 16,000 pages have the module installed incorrectly.

Module's creators

The user ivnish is maintaining the Drupal 7 module. Nobody maintains it for Drupal 8 at the moment.

What is the module used for?

The Hacked! module is an indispensable tool in the work of every professional Drupal agency. At Droptica, every new webpage accepted for Drupal support is being scanned with the Hacked! module for changes in modules.

We carry out checks in order to find any manual modifications to the Drupal modules and core. There are several goals for finding such changes:

  1. If possible, the Drupal core and contrib modules should not be changed. Drupal is a very flexible system, and, in most cases, you can achieve the desired results by acting according to good practices. If we find changes introduced by previous teams in the code, we try to transfer them to our modules and implement them in accordance with the Drupal standards.
  2. If the changes cannot be introduced into our own code, we move them to the tracked patches to be able to track them automatically and apply them with every module update.

We follow the above steps to be able to update modules easily and quickly to the latest versions without the risk that we will remove or break any functionality that someone has hidden in a contrib module. At this point, I encourage you to read the article on how to Keep Your Website Safe And Up-To-Date With Drupal Support.

Without the Hacked! Module, we do not have easy insight into changes introduced to a given contrib module, and in the case of an update, tracking down the modifications without using this module will be time-consuming.


In order to install the Hacked! module, go to the project's page at drupal.org or use the Composer we wrote a separate article:

composer require drupal/hacked

After the installation, you can configure the module by going to


The module has one configuration option:


Ignore line endings/include line endings: Depending on the operating system on which the module was modified, line endings are being determined differently. Setting this option to "Ignore line endings" will ensure that all line ending coding differences will be ignored.

In other words: if the developer opens the file in Windows and saves it while "Include line endings" is selected in these settings, then differences in line endings will be listed during the file check.

Generating a change report

After installing the module, go to


or use the drush command:

drush hacked-list-projects 


drush hlp 

The report generation process takes up to several minutes, depending on the number of files to be checked.

Review of changes

The Hacked! module provides a page with the report. We can find it under:


or by going to the "reports" tab in the admin menu, and then using the "hacked" link


In the given example, you can see that the module "Better exposed filters" contains some changes. Let us check them out:


If you have the additional Diff module, you can easily see the exact changes in each file:


Changes can also be observed using drush commands. In order to list the modules containing changes, use the command:

drush hlp


In order to list the names of the files containing changes, type:

drush hacked-details [the module machine name]

or use the alias:

drush hd [the module machine name]



In order to list the modifications in individual files in a given module, use the command:

drush hacked-diffd [the module machine name]

which will return changes between files in the same way that the git diff command does

Changes to the sample file:


Alternative modules

There are several file integrity checking modules, including MD5 Check, File Integrity Check, but they are not widely used. MD5 Check generates a checksum for files and on this basis informs the admin about changes. File Integrity Check, on the other hand, creates a "fingerprint" of the entire page and informs the admin if there are modifications to it.

Extension modules

We recommend installing the Diff module, which allows one to clearly track the changes between the current version of the file and the one downloaded by the Hacked! module.


The Hacked! module solves the problem of searching for modifications in the Drupal core and contrib module files. It provides a functionality which, in combination with the Diff module, allows you to see the differences between the original and modified files clearly.

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web