HomeDrupalSetting Up and Locking Down Secure Pages for Drupal

Setting Up and Locking Down Secure Pages for Drupal

Any Drupal website that deals with sensitive data (e.g. credit cards, medical records, etc) should have an SSL connection enabled in order to encrypt the transmission of said data back and forth from the website.

Unfortunately, installing securepages (a popular module for serving SSL enabled pages) can be a frustrating process for first time users. This goals of article are a) to get you up and running quickly while b) adding some additional security to your baseline configuration.

NOTE: This article assumes you have already purchased and installed your SSL certificates on the server(s) in question. This article also assumes you have applied the two core patches that have not been backported (yet) to Drupal 7 (specifically 471970-13 and 961508-21).

Setting Up

Once you’ve downloaded and enabled the module, you’ll want to make sure your .htaccess file is properly configured to resolve to either the www or non-www domain. This is important because securepages only allows you to specify ONE http domain and ONE https domain of your website (e.g. you can’t use http://yoursite.com and http://www.yoursite.com). And if a site’s .htaccess and securepages configurations don’t match, visitors can experience redirect issues (if they are able to load the website at all).

Assuming you want to keep the www version of the site, you would want to make sure the following lines of code are uncommented in the .htaccess file in the root Drupal directory.

RewriteRule ^ - [E=protossl]
RewriteCond %{HTTPS} on
RewriteRule ^ - [E=protossl:s]
RewriteCond %{HTTP_HOST} .
RewriteCond %{HTTP_HOST} !^www. [NC]
RewriteRule ^ http%{ENV:protossl}://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Once these are in place, you can enter in the following information through the UI at http://www.yoursite.com/admin/config/system/securepages. Here are my recommendations:

  • HTTP URL: http://www.yoursite.com
  • HTTPS URL: https://www.yoursite.com
  • Switch back to http pages when there are no matches.
  • Make secure pages only on the listed pages.
  • Pages (see below)

RECOMMENDATION! Do not set secure pages to “enabled” until you are 100% confident that you put the correct values in the other fields! The reason is that a misspelled domain name in the HTTP or HTTPS fields can result in an immediate redirection to the misspelled domain for all users (including admins). This means that you won’t be able to get to the UI screen to disable it because you’ll be redirected every time you try to get there. But have no fear, there is a way to get around this as I’ll describe later on in this article.

Once you have verified that everything is correct, simply enable the module. You may have to logout and log back in in order to clear out your session variables for the changes to take place. However, you should start seeing the HTTP to HTTPS redirects working as expected.

Locking Down

I have three issues with the UI approach:

  1. The possibility of getting redirected and getting locked out.
  2. The possibility of opening a security hole through a configuration change.
  3. Multiple development environments (staging, dev, and/or local) will need their own unique basepaths set at the time of load.

I’ve already discussed issue #1, but issues #2 and #3 are equally important. If you’re operating an ecommerce site where the credit card payments are being submitted to the Drupal application, then you need to make sure that those sections are locked down and cannot be easily disabled. And in an ideal case, you could even lock down these changes in a version controlled manner such that any changes could be reverted on a subsequent deploy.

In my opinion, the best way to address all of these issues is to add the securepages settings directly to settings.php. The following is an example I’ve used for several Drupal Commerce sites.


//ENABLE SECURE PAGES/SSL 
$conf['securepages_enable'] = "1";
$conf['securepages_basepath'] = "http://YOURSITE.com";
$conf['securepages_basepath_ssl'] = "https://YOURSITE.com";

// For HTTPS/HTTP to work, the following needs to be set TRUE for securepages.
$conf['https'] = TRUE;

//FORCE secure pages on sensitive areas 
$securepages_pages_paths = array(
  "node/add",
  "node/*/edit",
  "node/*/delete",
  "user",   
  "user/*",
  "admin",
  "admin/*",
  "cart",
  "checkout/*",
  "store*",
  "product*",
);
$conf['securepages_pages'] = implode("n", $securepages_pages_paths);

Issue #1

Is resolved because you can always turn off securepages (simply set securepages enable to “0”)or change the basepaths directly. Either way, you can no longer lock yourself out due to an incorrect configuration.

Issue #2

Is resolved because the variable set in $conf override any values previously held in the system variables table. And even if someone were to try and submit new values through an admin settings form, the values set in settings.php will continue to override those.

Added bonus

If the settings.php file is contained in the git repo, you can view any modification of this file in the git log. Also any changes made to this file on the server can get reverted on subsequent deployments.

Issue #3

Can be fixed by including environment specific flags within settings.php or loading a local.settings.php file. In both situations, you will no longer run into the situation where the newly copied database has the securepages settings in place for a different server, which would result in an immediate redirection to that other server!

I hope you found this helpful. And if you’ve found a way to improve upon it further, please let me know in the comments section below.