
We’re excited to hear your project.
Let’s collaborate!
With the Drupalgeddon2 "trauma" still “haunting” us all — both Drupal developers and Drupal end-users — we've convinced ourselves that prevention is, indeed, (way) better than recovery. And, after we've put together, here on this blog, a basic security checklist for Drupal websites and revealed to you the 10 post-hack “emergency” steps to take, we've decided to dig a bit deeper. To answer a legitimate question: “What are some good ways to write secure Drupal code?”
For, in vain you:
… if you leave its code vulnerable to various types of cyber attacks, right?
But most of all: What top secure coding practices should I and my Drupal development team follow?
Now, let's get you some answers:
SQL injections sure make one of the most “banal”, nonetheless dreadful types of attacks. Once such vulnerabilities are exploited, the attacker gets access to sensitive data on your Drupal site.
In other words: the proper use of a database layer makes the best shield against any SQL injection exploit attempts.
Now, let's talk... code.
For instance, linking together data right into the SQL queries does not stand for a secure coding practice:
db_query('SELECT foo FROM {table} t WHERE t.name = '. $_GET['user']);
In this case here, this is how you write secure Drupal code:
db_query("SELECT foo FROM {table} t WHERE t.name = :name", [':name' => $_GET['user']]);
Notice the usage of the proper argument substitution with db_query. The database abstraction layer uses a whole range of named placeholders and works on top of the PHP PDO.
Now, as for a scenario requesting a variable number of arguments, you can use either db_select() or an array of arguments:
$users = ['joe', 'poe', $_GET['user']]; db_query("SELECT t.s FROM {table} t WHERE t.field IN (:users)", [':users' => $users]); $users = ['joe', 'poe', $_GET['user']]; $result = db_select('table', 't') ->fields('t', ['s']) ->condition('t.field', $users, 'IN') ->execute();
There are some key Drupal security best practices to follow for addressing SQL injection issues:
Tip: remember to follow these coding practices for addressing and preventing SQL injections on your contrib modules, as well.
We could easily say that XSS attacks “rival” SQL injection attacks in “popularity”:
Drupal's highly vulnerable to cross-site scripting.
All it takes is some wrong settings — input, comment, full HTML — as you configure your website, to make it vulnerable to this type of attacks:
They make a convenient gateway into your website for remote attackers to use to inject HTML or arbitrary web.
Securing your Drupal 7 site against cross-site scripting attacks always starts with:
Identifying the very “source” of that submitted data/text.
Now, if the “culprit” is a user-submitted piece of content, depending on its type you have several check functions at hand to use for sanitizing it:
Note: always remember never to enter the user input as-is into HTML!
Tip: a good way to write secure Drupal code is to use t() with % or @ placeholders for putting together translatable, safe strings.
In Drupal 8, handling cross-site scripting attacks gets significantly easier.
Here's why:
Now, besides Twig, you have 3 more sanitizing methods at hand for fixing cross-site scripting issues in Drupal 8:
In order to check whether certain user inputs are vulnerable, all you need to do is:
Note: feel free to user Behat or another framework of choice to automate the whole process.
2 clear signs that you've detected an XSS vulnerability are:
Did you know that a lot of the Drupal security issues on your website occur precisely because you've skipped sanitizing the user-submitted content before displaying it?
And someone's neglect quickly turns into another one's opportunity...
By skipping to clean up that text beforehand, you lend the attacker a “helping hand” with exploiting your own Drupal site.
Now, getting back to why using Twig templates is one of the best ways to write secure Drupal code:
In short: securing your Drupal 8 website is also about having all HTML outputted from Twig templates.
One of Drupal's strongest “selling points” is precisely its granular permission system. Its whole infrastructure of user roles with different levels of permissions assigned to them.
Furthermore, there are all kinds of access controls that you can “juggle with”:
In short: you're free to empower users to access different sections/carry out different operations on your Drupal site.
How do you know whether there are access bypass flaws on your website, that could be easily exploited?
It's easy:
Do keep in mind that there are quite a few access callbacks to consider:
All you need to do is write automated tests to address any detected problems related to access bypass.
What does it take to write secure Drupal code?
Writing it... strategically, so that it should prevent any possible cross-site request forgery attack...
Now, here are 3 ways to safeguard it from such exploits:
In conclusion: a trio of good practices keeps the CSRF attacks away...
Now, after we've gone through some of the best ways to write secure Drupal code, let's see which are the most reliable contrib security modules to strengthen your site's shield with:
The END! This is how your solid Drupal security “battle plan” could look like. It includes:
What ways to write secure Drupal code would you have added or removed from this list?
We’re excited to hear your project.
Let’s collaborate!