The 10 most critical Drupal security risks:
- SQL Injection
- Cross Site Scripting (XSS)
- Authentications and sessions
- Insecure direct object references
- Cross Site Request Forgery (CSRF)
- Security misconfiguration
- Insecure cryptographic storage
- Failure to restrict URL access
- Insufficient transport protection
- Unvalidated redirects
1. SQL Injection
You shouldn't use data that you don't trust (as a feed, a user input, another database, etc) directly in a database query without escaping it. This has been possible in Drupal 7 using functions that are now deprecated in Drupal 8.
db_query('SELECT foo FROM {table} t WHERE t.name = '. $_GET['user']);
Even though deprecated functions in Drupal 8 are available for us to use, we should be avoiding them. They are included only to allow legacy code to work more easily on Drupal 8.
Instead you should use the Drupal 8 object oriented method of building a query. In the example below, the $name variable will be sanitised, but there won’t be any user access permissions checked automatically.
$query = $connection->select('table', 't') ->fields('t', array('foo')) ->condition('t.name, $name);
If you need to include dynamic table names in your query, you should use escapeTable()
2. Cross Site Scripting (XSS)
XSS enables attackers to inject client-side scripts into web pages in order to carry out malicious actions. A large proportion of security vulnerabilities on web applications are XSS, so it makes sense to understand them and avoid them.
You should always escape the variables you send to the output if they come from a non trusted source, like the parameters of a URL. For example, this code is insecure:
print $_GET['id'];
It's also very common to see code like this, specially in custom themes:
$output .= $node->title;
The problem in the code above is that Drupal doesn't usually filter the user input when a node is saved. So the user could save malicious code in the title and then it will be printed without any kind of filtering.
One more obvious mistake is giving full HTML permissions to users who aren’t trusted, or allowing use of unsafe tags as <script>.
So, what can you do?
Luckily, the Twig templating engine that Drupal 8 uses now sanitises all variables by default. Ideally, all your HTML output should be from Twig templates.
Drupal also includes other API functions that you should use where appropriate. The Drupal 8 security documentation recommends the following functions:
- Use t() and \Drupal::translation()->formatPlural() with @ or % placeholders to construct safe, translatable strings.
- Use Html::escape() for plain text.
- Use Xss::filter() for text that should allow some HTML tags.
- Use Xss::filterAdmin() for text entered by a admin users that should allow most HTML.
- Use Drupal.t() , Drupal.formatPlural() in JavaScript.
3. Authentications and sessions
You need to deal with these issues:
- Weak password storage and account management
- Session hijacking / fixation
- Lack of session timeout / logout
Luckily, Drupal has good solutions for these built in.
- Like Drupal 7, Drupal 8 stores passwords in the database in hashed form. This means that anyone who gets access to the database does not get access to user’s passwords.
- In Drupal 8, the user’s session data is also stored in the database in hashed form. This means sessions can’t be hijacked by anyone with access to the database.
4. Insecure direct object references
It’s possible to load a node without checking that the user has access to it. For example, this will load the node a node with a certain id:
$node = \Drupal\node\Entity\Node::load($nid);
The Drupal 8 approach is to use $node->access($operation) to determine if the user has permission to perform a particular operation on the node.
When using Views, sometimes we don't make sure the user has access to nodes. One common issue is forget to add "published = Yes" to the view filters.
5. Cross Site Request Forgery (CSRF)
Below is an example of an image tag that could be added by any user who has permission to enter full HTML. When a user loads the page with this tag they will be logged out.
<img src="http://example.com/user/logout" />
It would be possible to delete content in the same way:
<img src="http://example.com/node/12/delete" />
However, in this case Drupal always asks "Are you sure you want to delete...?" when you try to delete an item to mitigate the risk of this happening.
This is an illustration of why it’s important to grant the ability to use Full HTML only to your trusted users. It’s also important that we use the Drupal API to achieve what we need wherever possible. The Form API includes input validation and security features that will mitigate the risk of a CSRF attack. For example, you should always make sure that you have a confirmation form for any critical custom operations (such as deleting content) so that nothing bad can happen if it’s linked to directly.
6. Security misconfiguration
Secure server
- Make sure that your file permissions[https://www.drupal.org/node/244924] are appropriate to prevent unauthorised file access.
- Control the maximum POST size and maximum file upload size by settings these in the php configuration on your server. Without this, attackers are able to upload large files or send large POST requests to use up system resources.
- FTP is a vintage technology and was not designed to be secure. It includes a list of vulnerabilities that are well documented HERE. Use a version control system like git or at the very least SSH / SCP to get files onto your server.
- Once you’re using SSH / SCP, consider using keys instead of passwords. This is an easier, more secure and more reliable way of signing into your server.
- Keep your operating system up to date. Common Linux distributions will have an update system that will prompt you to do this.
- Don’t have unnecessary applications running on a server. The more applications you have, the more software you’ll need to keep updated and the more likely it is that one of them will expose a security flaw.
Secure Drupal
- Is your admin password strong enough? Use a password tool such as KeePass or LastPass to generate a secure password that you don’t use on any other sites and to keep track of all your passwords.
- Double check all the "administer *" permissions and make sure they’re only assigned to trusted user roles. The "Administer text formats and filters" permission can allow a user to take control of a site.
- Use Update module and keep track of the security news. Security updates are made on Wednesdays.
7. Insecure cryptographic storage
You may find that you develop custom modules that need to store sensitive data. There’s no native way in Drupal to do two-way encryption (i.e. to encrypt data that you’ll want to decrypt again later). If your database or a backup copy of your database is accessed, then you could be exposing sensitive data.
There’s a contributed module called Encrypt which provides an API you can use to encrypt the data you need to.
8. Failure to restrict URL access
If your custom module implements custom routing using Drupal 8’s new routing system, make sure that access permissions to your URLs you create are set properly. In Drupal 8, routing is done with YAML configuration. For example, the following would allow anyone who can access content on your site to access the path /example/settings.
example.name: path: '/example/settings'
defaults: _controller:'\Drupal\example\Controller\
ExampleController::content' requirements: _permission:
'access content'
Make sure that this is what you want and if it isn’t, check out the routing documentation to see how to achieve the access settings you need.
9. Insufficient transport protection
Tools like Wireshark allow you to analyse network traffic on the network you’re connected to. Using such a tool, a person connected to the same Wifi network as you in your office or in a coffee shop can see any unencrypted data you’re sending or receiving.
Configuring your server to allow access to your Drupal site over an HTTPS connection will allow your users to visit your site securely. You’ll require an SSL certificate that allows a user’s browser to confirm that the login page is not a forgery and it encrypts the username and password when it’s sent over the network. This prevents malicious people from stealing your login details.
10. Unvalidated redirects
The original security blog post contained unvalidated redirects as a separate security issue. However, we consider that this is now really a combination of the issues discussed under point 5: Cross Site Request Forgery, so won’t go into this further here.
No comments:
Post a Comment