Encryption is Not So Easy
This morning, during my usual scan of Feedly/Twitter/Reddit I read Secure the data of visitors on your Drupal website better. The post shows you how to use the Field encryption module.
The Field encryption module ensures that the values stored in the Drupal database are encrypted. When the database ends up in the wrong hands, then nobody can read the data since this module has encrypted it. This way, you are prepared for a worse case scenario.
It all seems straight forward enough, but I suspected it wouldn’t be so simple and in fact doesn’t look as secure as purported. My main concern was with the 3 options presented for storing the private key used to encrypt data. So I asked on Twitter:
How secure is this if Drupal needs to read the key? http://t.co/q8wzlLy2dM /cc @enygma @Awnage @ircmaxell
— Oscar Merida (@omerida) October 7, 2015
Now, this post isn’t meant to denigrate the work of that project or to completely discount the advice on openlucius.com. Let’s see why some of the ways to store the key are problematic.
@enygma @omerida @Awnage the key is stored in the db? o_O
— Anthony Ferrara (@ircmaxell) October 7, 2015
The first option is to store the key in the database, and at least the article recommends against selecting that. If your key is in the database, and a malicious attacker manages to steal your database or find some way to read it’s contents via SQL Injection, they will have your key. With the key, nothing will stop them from unencrypting your data.
The second option is to specify it as a variable in settings.php
. The key is a little harder to get but is only a variable_get('encrypt_drupal_variable_key')
call away. Since settings.php
is in the public web root, misconfiguring PHP or having PHP files show the source code will leak your key too. Finally, if you’re committing your settings files to git or SVN (hint: you shouldn’t be), anyone with access to your repository will also have your key.
@omerida imho they should only offer the last option. @ircmaxell @Awnage
— Chris Cornutt (@enygma) October 7, 2015
The final option, to use a File should be the recommended way to specify the key. Ideally, the file is somewhere outside of your web root and, again, not in your code repository.
Only in option 1 is your key vulnerable to SQL injection attack. For the other 2 options, an attacker would have to gain access to your code to get your key. Given how Drupal 7 stores routes in the database, all that takes is and SQLi vulnerability in another module or core itself and someone could install a back door or shell on your site.
@omerida @enygma @Awnage depends on a lot of factors. If done correctly (haven't looked yet), could make SQLi virtually useless by itself.
— Anthony Ferrara (@ircmaxell) October 7, 2015
No matter how you store it, if you have the PHP module enabled, anyone who can build a view or execute PHP code from the Drupal UI can retrieve your key. There’s also a temptation to share the key across development, testing, and production environments so that your database snapshots are portable between them all.
Others brought up issues on as well. The original module author added a comment highlighting that the Field Encryption module is still marked as Beta, which was released in 2013.Also, there are better key management solutions for Drupal.
@enygma @ircmaxell @omerida @Awnage the default options are bad, bad, and bad. Modules like townsec_key & key attempt to provide real KMS
— Cash Williams (@cashwilliams) October 7, 2015
Also, there are better algorithms for encryption than those in the module.
@ircmaxell @enygma @omerida @Awnage It's worse than that, the suggested plugin Encrypt, uses ECB & mcrypt with no authentication. *shrug*
— Ashley Pinner (@NeoThermic) October 7, 2015
Security is a Continual Process
This illustrates that security is a continual process, with a lot of considerations to take into account. It’s not as easy as installing a single module or ticking a box on a check list. If you’re storing really sensitive user data, ask yourself if you really need it. If this data is credit card information—get to know what it takes to be PCI compliant. Then ask if you aren’t better off using a payment processor instead. But please, don’t be lulled into a false sense of security after adding a single component.
Leave a comment
Use the form below to leave a comment:
Responses and Pingbacks
October 7th, 2015 at 5:42 pm
While I absolutely agree that security is hard to get right and needs lots of scrutiny, the default Drupal 7 private key is _not_ stored in the database.
And as long as its used as a hash_hmac of another thing it should be fairly okay to use for encrypting data.
Obviously putting it in a file is best, but even then a simple key reading can occur if the module supports an API – so it is not necessarily worse than variable_get.
And variable_get can perfectly be only used with a properly secured private settings file.
October 16th, 2015 at 3:09 pm
As one of the developers working with the group of developers around the encrypt modules in Drupal I can’t thank you enough for bringing to light the issues we’re trying to push through the community, namely that keys are NOT safe in the database, code (and really even on the same server).
Until recently with our efforts on Key, key management in Drupal hasn’t been in the forefront of the discussion but luckily that’s beginning to change. With the Key module we set out to provide an easily pluggable module where keys for encryption (and API keys which are just as important) to be routed through a central place and hopefully stored properly.
We’ll all be the first to admit that storing the key in the settings.php or the database **shudder** should NOT be done. But we have to give developers options to work with as they build their system. We are pushing proper key management must be done offsite. After looking at the options out there we built an integration with Townsend’s Alliance Key Manager because it offered a good solution. Then as we continued to build it saw the needed for a saas platform for key management which lead us to build Lockr (https://lockr.io).
Thanks for keeping the conversation going and focusing a light on this issue! Encryption isn’t easy, but the steps should be simple. Which is what we’re hoping to provide as things continue to build.
November 20th, 2015 at 12:25 pm
Great post, thanks for sharing. I hope it is not true that Drupal saves passwords in the database, it can be a major security breach.
December 9th, 2015 at 3:58 pm
Arturo,
Well, it *does* save user password in the database for authentication but they are hashed, like any other good application would do. In this case, I was concerned that the Encryption keys were being saved to the DB or Filesystem, where they are easily accessible.