Last updated February 20, 2017. Created on November 11, 2009.
Edited by marcus7777, DamienMcKenna, TravisCarden, yidanzhu. Log in to edit this page.

HTTPS is a protocol which encrypts HTTP requests and their responses. This ensures that if someone were able to compromise the network between your computer and the server you are requesting from, they would not be able to listen in or tamper with the communications.

When you visit a site via HTTPS, the URL looks like this: https://drupal.org/user/login. When you visit a site via plain (unencrypted) HTTP, it looks like this: http://drupal.org/user/login.

Why is it important to you (and when)

HTTPS is typically used in situations where a user would send sensitive information to a website and interception of that information would be a problem. Commonly, this information includes:

  • Credit cards
  • Sensitive cookies such as PHP session cookies
  • Passwords and Usernames
  • Identifiable information (Social Security number, State ID numbers, etc)
  • Confidential content

Especially in situations where you, as the administrator, are sending your Drupal password or the FTP password for your server, you should use HTTPS whenever possible to reduce the risk of compromising your web site.

HTTPS can also prevent eavesdroppers from obtaining your authenticated session key, which is a cookie sent from your browser with each request to the site, and using it to impersonate you. For example, an attacker may gain administrative access to the site if you are a site administrator accessing the site via HTTP rather than HTTPS. This is known as session hijacking and can be accomplished with tools such as Firesheep.

Security is a balance. Serving HTTPS traffic costs more in resources than HTTP requests (both for the server and web browser) and because of this you may wish to use mixed HTTP/HTTPS where the site owner can decide which pages or users should use HTTPS.

How to enable HTTPS support in Drupal

Web server configuration

  1. Get a certificate. many hosting providers set these up for you - either automatically or for a fee. Simply ask your hosting provider. If you want to secure a test site, you could instead generate a self-signed certificate.
  2. Configure your web server. A few helpful links:

    Chances are, your webhost can do this for you if you are using shared or managed hosting.

Note: Clean URLs If you're using Apache for HTTP and HTTPS:

You will probably have two different VirtualHost buckets.

  1. A bucket for port :80 http
  2. A bucket for port :443 https

Each of these VirtualHost containers or buckets require that a specific Apache directive be added within them if you're using Clean URLs. This is because Drupal makes extensive use of .htaccess and mod_rewrite to provide friendly URLs.

Ensure you have the following within the directive, which is a child under the VirtualHost container: See Apache Documentation for AllowOverride

 <Directory "/path/to/yoursite">
AllowOverride All
 </Directory>

This means that your .htaccess takes precedence and that the Apache configuration will allow it to run as you would expect for Drupal.

Troubleshooting:
If you enabled HTTPS and it only works on the homepage and your sub links are broken, it's because the VirtualHost:443 bucket needs AllowOverride All enabled so URLs can be rewritten while in HTTPS mode.

Drupal configuration

  • On Drupal 7, if you want to support mixed-mode HTTPS and HTTP sessions, open up sites/default/settings.php and add $conf['https'] = TRUE;. This enables you use the same session over both HTTP and HTTPS -- but with two cookies where the HTTPS cookie is sent over HTTPS only. You will need to use contributed modules like securepages to do anything useful with this mode, like submitting forms over HTTPS. While your HTTP cookie is still vulnerable to all usual attacks. A hijacked insecure session cookie can only be used to gain authenticated access to the HTTP site, and it will not be valid on the HTTPS site. Whether this is a problem or not depends on the needs of your site and the various module configurations. For example, if all forms are set to go through HTTPS and your visitors can see the same information as logged in users, this is not a problem.

    Note that in Drupal 8, mixed-mode support has been removed #2342593: Remove mixed SSL support from core.

  • For even better security, send all authenticated traffic through HTTPS and use HTTP for anonymous sessions. On Drupal 8, install Secure Login module which resolves mixed-content warnings. On Drupal 7, leave $conf['https'] at the default value (FALSE) and install Secure Login. Drupal 7 and 8 automatically enable the session.cookie_secure PHP configuration on HTTPS sites, which causes SSL-only secure session cookies to be issued to the browser. On Drupal 6, see contributed modules 443 Session and Secure Login.

  • For best possible security, set up your site to only use HTTPS, and respond to all HTTP requests with a redirect to your HTTPS site. Drupal 7's $conf['https'] can be left at its default value (FALSE) on pure-HTTPS sites. Even then, HTTPS is vulnerable to man-in-the-middle attacks if the connection starts out as a HTTP connection before being redirected to HTTPS. Use the HSTS module or Security Kit module, or set the Strict-Transport-Security header in your webserver, and add your domain to the browser HSTS preload list, to help prevent users from accessing the site without HTTPS.

    You may want to redirect all traffic from http://yourdomain.com and http://www.yourdomain.com to https://youdormain.com. You can do that by adding this to your .htaccess file:

    RewriteCond %{HTTPS} off [OR]
    RewriteCond %{HTTP_HOST} ^www\.example\.com*
    RewriteRule ^(.*)$ https://example.com/$1 [L,R=301]

    Put that below RewriteEngine on.

    There are existing comments in .htaccess around line 95 that explain how to redirect http://example.com to http://www.example.com (and vice versa), but this code here redirects both of those to https://example.com.

Looking for support? Visit the Drupal.org forums, or join #drupal-support in IRC.

Comments

Jephir’s picture

This article recommends to "setup your site to only use HTTPS, not even responding to HTTP with a redirect." How would this be done?

mfb’s picture

Depends what webserver you're using. For example, if you use Apache httpd, you'd have just one apache VirtualHost for your drupal site with SSLEngine on.

jvieille’s picture

I want all my site to be https.
Unfortunately, my credit card processing gateway does not support ssl for the payment response (!!!)
This specific page /cart/atos/autoresponse has to be hit by http.

I put these lines in botyh :80 and :443 virtual hosts

RewriteCond %{REQUEST_URI} !^/cart/atos/autoresponse$
RewriteCond %{HTTPS} !on
RewriteRule ^(.*) https://%{HTTP_HOST}%{REQUEST_URI}

This does not work properly. When I send
http://www.mysite.com/cart/atos/autoresponse

the url is changed to
https://www.mysite.com/index.php?q=cart/atos/autoresponse

What's wrong?

Thanks for help

JV

crimsondryad’s picture

If you only use the 443 Virtual Host, what happens when the user types in http:// instead of https:// ? Will apache correctly server the site as ssl or will it not be found? This is obviously a user education issue, but most companies can't afford to risk losing the $$ if visitors can't find their sites.

Maybe we should just make the whole web ssl end to end.... :P

amxcld9’s picture

Does this mean that Drupal 6 cannot do mixed mode HTTPS?

If D7 supports mixed mode which 99% of secure connections are I would presume.

Such as logging in/out using SSL and normal unsecured for everything else.

Anyone know the answer here?

Edit: I found the answer here: http://drupal.org/project/securepages

Thanks

crimsondryad’s picture

We don't use the secure pages module because we have higher security requirements. We wanted our logins forced to ssl in an area that very few people have access to and would not be able to turn off by accident easily.

Because only admin users are logging in right now, we used a mod_rewrite rule to look for /user, /admin type paths and force to SSL. This isn't a perfect solution though, sometimes it causes errors with views because (there's an issue for it on d.o.) sometimes ahah calls are made and the path isn't /user or /admin so it borks the ssl? (Sorry, been a while since we looked at this...memory is somewhat faulty).

Though honestly, with Firesheep and the like, switching back and forth from http to https and back again with real user logins is a recipe for disaster. A better method would be to require the entire site to use ssl.

dalin’s picture

As @crimsondryad points out, using mod_rewrite is much more difficult than it originally appears. The _only_ two ways to have a site safe from session hijacking in D6 is to use 443 Session module or have your site use only HTTPS and ignore HTTP.

________________________
dave hansen-lange
Technical Manager
Advomatic.com
Great White North office
Canada

waqarit’s picture

If you want to redirect all of your pages to be forced to use SSL then add this to your .htaccess file.

# Redirect to HTTPS
RewriteCond %{HTTPS} off
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

I would preferably add this at the bottom of the file just encase you have any exceptions for example certain pages that you don't want redirected.

dumme’s picture

This is how I got my entire site to HTTPS. (Special thanks to charginghawk who helped me fix it).

# Various rewrite rules.
<IfModule mod_rewrite.c>
  RewriteEngine on

  RewriteCond %{HTTPS} off
  RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

  # Set "protossl" to "s" if we were accessed via https://.  This is used later
  # if you enable "www." stripping or enforcement, in order to ensure that
  # you don't bounce between http and https.
  RewriteRule ^ - [E=protossl]
  RewriteCond %{HTTPS} on
  RewriteRule ^ - [E=protossl:s]

  # Make sure Authorization HTTP header is available to PHP
  # even when running as CGI or FastCGI.
  RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

Please note, this site is redirecting all users to the "WWW" version of the site. With the .htaccess code as is currently listed in this node, I got an infinite redirect loop and the website would not resolve. The above code is straight from my .htaccess and my site is fully HTTPS.

As a side note, I really think switching to a fully HTTPS site should be 'easier', even for novices. Looking up 'solutions' on the web turned up several variances, and they did not work for my configuration.

I hope this helps someone, and thanks again to charginghawk for figuring it out for me!

FreeXenon’s picture

Not too painful:

  1. In the domain settings I set it to rewrite to www.
  2. In the settings.php I set the base url to https:
  3. in the .htaccess I use the above code.

Thanks for all for all of the work! =)

dalin’s picture

You can run the HTTP site from a different server and simply deliver a plain text message telling your users to use HTTPS.

________________________
dave hansen-lange
Technical Manager
Advomatic.com
Great White North office
Canada

benblb12345’s picture

I think to you
----------------
Khuyen mai

bike2live’s picture

Currently the global variable $is_https is set from the runtime settings based on the local apache settings. However there are configurations where the SSL is handled by an upstream machine which only communicates un-encrypted to the server on which Drupal is running. In this scenario, the $is_http is always false, but needs to be true (for proper redirects, etc.). If there were a hook which sets the $is_https variable, then we could override this hook and implement the code that we need to set this variable correctly (based on header information injected by the upstream machine). As is we have to modify boostrap.inc - which of course is taboo.

I'm not sure if there is a better avenue to provide suggestions. If so please educate me.

Fleshgrinder’s picture

Thank you so much for your comment, I was going nuts with my nginx server because Drupal always delivered everything via HTTP and didn't realize that I'm using HTTPS. I just altered the Bootstrap.inc file and set $is_https = 'on'; so I always have a HTTPS connection.

QN2tech’s picture

i have the same perspective too

erlendstromsvik’s picture

It would not have to be a hook. Just let settings.php override the value.
There is already a value for settings.php named $conf['https']. This settings obviously has nothing to do with $is_https. Why? I have now idea. It should tho.

John Morahan’s picture

You can set $_SERVER['HTTPS'] = 'on'; in settings.php then bootstrap.inc will pick that up later when setting $is_https.

benjen’s picture

My Drupal did not recognize it was running via https and therefore the module fontyourface pulled the google-fonts via http, which led the browser only load the fallback fonts. Thanks to your advice, fontyourface works, thanks!!

Bairnsfather’s picture

I am at the point of making one of my sites (in a multisite install) be https. Based on what I’ve read at eff.org (HTTPS Everywhere, How to Deploy HTTPS Correctly, HTTPS Everywhere FAQ) and elsewhere the past few years, I’m ready to make at least one of my sites HTTPS-only. I’ve tried a number of methods and am having trouble.

In the site’s settings.php files I uncommented and changed the line:
$base_url = 'https://example.com'; // NO trailing slash!

But that didn’t force pages to load https.

I figured maybe I could isolate this one site out of my multisite setup and adjust the .htaccess file somehow, but that hasn’t worked either. As is pointed out in the comments above, it seems like it should be so simple. On DRUPAL AND SSL - MULTIPLE RECIPES TO POSSIBLE SOLUTIONS FOR HTTPS, at the end is what seems to be the best advice, and what I want to do, “Just Make All Drupal Pages SSL” but adding that chunk to my .htaccess file just gives me an Internal Server Error.

I don’t have access to the Apache conf file.

I’d prefer not to install a handful of modules. But until I can find out how, is that the only way?

Also, it’s not entirely clear how or why a redirect is insecure. If the redirect is in the .htaccess (or conf) shouldn’t that mean it’s done before Drupal assigns a cookie?

Bairnsfather’s picture

Update - I was very glad to find out the 443 Session module has the option to force all traffic over https. Unfortunately I was not able to determine this from the project page, only after I installed it.

However, I’m still foggy on this redirection thing.

Then there is the issue of looking at the cookie in the browser and it saying the cookie is not secure. Hm, so many details. :-)

Reading this: http://en.wikipedia.org/wiki/HTTP_cookie#Terminologies it says

A secure cookie is only used when a browser is visiting a server via HTTPS, ensuring that the cookie is always encrypted when transmitting from client to server. This makes the cookie less likely to be exposed to cookie theft via eavesdropping.

I can understand the cookie is transmitted securely since it’s https, but apparently that is apart from the cookie being encrypted? My needs are modest so perhaps I am sweating the small stuff?

Bairnsfather’s picture

Since someone wrote me and said s/he was having the same issue as me, I will describe what I did.

I installed 443 Session. It was that simple. :-) In the admin page is the option to force all traffic over https (upon initial reading of the page it was not clear this option existed, that’s why I hunted around and posted here).

It’s still not entirely clear exactly how the man-in-the-middle attack could work on this method (I didn’t dig around in the module to try to figure it out then Google for answers), and perhaps DNSSEC could play a role, but …

I hope that helps.

Bairnsfather’s picture

Just noticed this in my news reader:

How secure is HTTPS today? How often is it attacked?
https://www.eff.org/deeplinks/2011/10/how-secure-https-today

crimsondryad’s picture

The man in the middle attack is caused when someone intercepts the http traffic and routes it through another server before sending to https. This is where an attacker would intercept a http cookie before it's transitioned over to https (or vice versa, though enforcing separate cookies for http and https is supposed to mitigate this). So this module makes configuring paths better and it is an improvement in some ways over modifying via .htaccess or apache vhost, but it isn't a bulletproof option ( which is basically to turn off the http Virtual host entirely in apache and ONLY answer on the port 443 virtual host ). As discussed before though, turning off http entirely comes with a rather glaring flaw.

We live in an imperfect world. :P

dalin’s picture

443 Session module does use separate session cookies for HTTP/HTTPS which reduces the methods of exploitation to things like hijacking a router near a CA authority, or hacking into a CA authority. If someone is willing to go to that much effort, they would probably have much more success breaking into your website via some simple social hacking.

________________________
dave hansen-lange
Technical Manager
Advomatic.com
Great White North office
Canada

Sheldon Rampton’s picture

Here are some suggestions including Apache configuration to force SSL encryption on Drupal pages:

http://groups.drupal.org/node/135824

----------------
Open Data Technology Manager, GovDelivery
https://govdelivery.com

pszpak’s picture

Is there a simple fix for all links beyond the front page not working after enabling https? The paths seem to be wrong, but I don't know how to fix this.

Bairnsfather’s picture

More info needed. Like a link to your site. Off-hand the only thing I can think of is there are hard coded absolute paths that are failing.

(Note that per good Drupal style, support questions should be in the forums.)

crimsondryad’s picture

If you're using an apache vhost, note that your redirects have to be set up in the port 80 vhost AND the port 443 vhost. Usually the easiest way to do that is to copy the redirects to an external file ( like domain.com.redirects ) and include that in both vhost mod_rewrite sections.

timdaman’s picture

All,
I struggled a long time to get my configuration working and thought it best to post a simple summary of what I needed to do so others would not need to reinvent the wheel.

I have a website hosted on drupal that is being run on Apache. This Apache webserver is sitting behing a load balancing device that among other things terminates TLS traffic and converts it to plain-text http over port 4430. Thus my apache server receives 2 traffic flows, one over port 80 and one over port 4430, both of which are plain-text http. On the virtual host listening to port 80 I have a simple redirect that looks like this

#redirect all traffic to https
                RedirectMatch permanent ^(.*)$ https://www.example.com$1

On the virtual server listening to port 4430 I have the traffic flowing to Drupal. The problem was Drupal did not know it was dealing with https so it was sending back "http://" links which caused the dreaded mixed or insecure content errors. I found putting the following in the setttings.php simply and easily induced Drupal to treat all it's traffic as being "https://".

$_SERVER['HTTPS'] = 'on';

Those were the only changes I needed to do.

IWasBornToWin’s picture

For best-possible security, setup your site to only use HTTPS, not even responding to HTTP with a redirect. HTTPS is vulnerable to man-in-the-middle attacks if the connection starts out as a HTTP connection before being redirected to HTTPS. $conf['https'] can be left at its default value (FALSE) on pure-HTTPS sites. You can run the HTTP site from a different server and simply deliver a plain text message telling your users to use HTTPS.

This is confusing. It appears you say to make site secure, add $conf['https'] TRUE but then you say if you really want it secure just leave it at false and run your whole site as secure.

OK, so do we still add it? It's not already in the settings files. And it simply "leaving" it the way it is makes me think I dont need to add it. Well, that means nothing would change, right? Therefore site still would not be secure.

So, I added it and it works, now https pages are working (After I also changed my base url).

now, unless I am missing a step, my site can still be accessed via http. How do we make the whole site only be able to use https? And how to you do a server side redirect automatically from http to https? I tried changing my refirect in .htaccess but that didn't work.

Thanks

IWasBornToWin’s picture

I was able to achieve the redirect by adding these two lines to my .htaccess file

RewriteCond %{HTTPS} off
  RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
ressa’s picture

I am getting a redirect loop when I put that in my .htaccess file.

But the 443 Session module worked out of the box, redirecting the desired pages from HTTP to HTTPS, either all of them or for example just pages under the cart/* path. I was getting a yellow warning triangle on pages with a "Like on facebook" link, but changing HTTP to HTTPS in the Facebook iFrame link fixed it.

EDIT: To make it work, I had to remove HTTP: from the link like this: src="//www.facebook.com/plugins/like.php?href=example.com&layout=button_count&show_faces=false&width=170&action=like&colorscheme=light&height=21"


Try Drupal 8 at simplytest.me
jrz’s picture

Hi timdaman,

I also have the same setup. But now I need to run a site using mixed http and https traffic. The primary reason is to only encrypt forms and the admin section. Do you have any suggestions with configuration?

cdnsteve’s picture

I've updated the docs to include specific configuration notes for Apache using Clean URL's with HTTP and HTTPs. I hope this is helpful for others.
Thanks,
Steve

ELS Landscape’s picture

If you do not know how to set your server to serve only HTTPS then contact the host.
There is also a place to have drupal create HTTPS and HTTP in the same directory so this should fix any broken links.

The next issue is to make sure if your theme calls up external CSS that you change that to https too.

as an example

If you do this an have a verified cert you will get the green bar and no errors.

You also have to be careful about serving some images from unsecrure locations. I am having an issue with a mod doing that but will not call out until I know more about it. Chrome inspect element was very helpful in finding it and it seems to be an insecure FB profile Icon. The page at https://www.example.com/node displayed insecure content from

http://profile.ak.fbcdn.net/static-ak/rsrc.php/v1/y6/r/ksUwmHUElCY.jpg.

You do not have to change the sites/default/settings.php

yurtboy’s picture

APC, Memcache/Varnish, and just drupal cache in general?
Are these effected by forcing https on all URLs?
I know the users browser may not cache as well but just wondering about these cache layers?

Thanks

heathernorvell’s picture

You might not find this helpful, but there are comments about Drupal on this blog post about Varnish and HTTPS, and for the sake of future people here:

https://www.zivtech.com/blog/implementing-pound-varnish-lamp-setup-achie...

bulldozer2003’s picture

At the bottom of the blog you've posted is a dead-simple fix for Drupal/Apache sites behind a reverse proxy:

Since the Apache server doesn't have SSL enabled, a Drupal instance on that server will not properly work over SSL. In order to actually get Drupal to recognize the cert we must alert Apache to enable the HTTPS flag. We do this in our VHost file. All we need is to add a line to the VirtualHost configuration:

SetEnvIf X-Forwarded-Proto https HTTPS=on

MakeOnlineShop’s picture

Ubercart UC_SSL module works immediately and Stripe is so good and easy to use.

Ubercart is still the easiest e-commerce module for Drupal in my opinion and offers more than enough to 99% of the people who should not waste their time with any other commerce module !

Thanks again.

sstedman’s picture

Acquia Cloud users, please note the use of {HTTP:X-Forwarded-Proto} in your .htaccess to achieve redirects. Took me an age to find this info, so reposting from acquia to here:

# Redirect to HTTPS
RewriteCond %{HTTPS} off
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
duckydan’s picture

Thanks sstedman. I was pulling what little hair I have left out. That worked perfectly.

Dan Eveland

bjdeliduka’s picture

As the subject says.... the Joys.

A client of mine has numerous customers with Drupal 7 sites. We are moving all of them behind CloudFlare (www.cloudflare.com) we they offer FREE SSL Certs, web caching, and ddos protection/mitigation. We then firewall the servers to only accept connections from the CF Caches and make sure that the actual HTTP Server is not listed in DNS (client/browsers should connect to the CF Servers which will then fetch pages from the actual server). The Drupal Server (apache 2.4 on centos) also use SSL to encrypt the connection between CF and the server (might as well keep everything out of plain text )

While the above looks and feels like a great solution to insuring all connections are encrypted we encountered a problem with some pages that have IFRAMES that load encrypted content. (web browsers throw an error when this occurs and often refuse to load the content without user intervention).

Options included 1) setting up a proxy and encrypting the insecure content. While technically possible it gives the user the impression the session is secure while some of the content is in plain text (though not to/from the client). 2) drop the content until it's available via a secure connection (client/customer did not like this option) 3) force pages that contain this content to be unencrypted (http) connections while the rest of the site is encrypted.

We chose option 3.

The sites had been previously configured to redirect connections to https using a rewrite rule in the .htaccess file (will probably move these into the vhost config files for performance reasons but only if we can agree on disabling the .htaccess files) As such every http connection becomes an https connection.

Normally a rewriterule could be created in the form:

RewriteCond %{REQUEST_URI} ^Streaming-Page.* [NC]
ReWriteRule ^/?(.*) http://%SERVER_NAME}$1 [R,L]
ReWriteRule ^/?(.*) https://%SERVER_NAME}$1 [R,L]

to catch connections to the page with the insecure iframe. (rewrite matching to http and non-matching to https)

try this with clean url's enabled and you never get the unencrypted page because every page request submitted to drupal does a final pass through the rewrite engine on /index.php.

I'm unsure of the exact reason but secure_pages were not considered a viable option.

The end result solution is a series of 13 rewriterule/rewritecond lines that can effectively replace the secure_pages module for forcing all but a select few (1 or more) pages to https connections.

RewriteCond %{REQUEST_URI} /index.php
RewriteRule ^ - [S=6]
RewriteCond %{REQUEST_URI} !^/Streaming-Page.* [NC]
RewriteCond %{REQUEST_URI} !^/$ [NC]
RewriteRule ^ - [S=4]
RewriteCond %{HTTPS} on
RewriteRule ^/?(.*) http://%{SERVER_NAME}/$1 [R,L]
RewriteRule ^ - [S=3]
RewriteCond %{HTTPS} on
RewriteRule ^ - [S=1]
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
RewriteCond %{HTTPS} !on
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]

/Streaming-Page and the root page of the site are HTTP the rest of the site is HTTPS. Additional pages can be excluded from HTTPS by adding additional likes under the /Streaming-Page line following it's format.

The only known side affect of this code is that editing unencrypted pages is more complicated as the admin_menu drops on the unencrypted pages. Version 1.1 will include a method of disabling the http side from a clients browser (resulting in the browser errors that developers will deal with as needed while editing the pages) I'll also look an more detailed instructions on putting this into .htaccess files and removing unwanted/unneeded code for things like www. stripping (or pre-pending) etc

danillonunes’s picture

There’s nothing more secure in stop serving HTTP pages, as the last list point says. That paragraph should be removed entirely from this page. Let me be clear about this: Avoid serving content to a HTTP request improves security in no more than 0%.

If your user is accessing your page through an insecure channel, and they suffer a man-in-the-middle attack, it doesn’t matter what you actually serve, the MiM is already in control. They are in the control, not you. At this point there’s nothing really you can do. The MiM might as well redirect to their own fake HTTPS page.

If your user is accessing your page through an insecure channel are not attacked, then sending an automatic redirect or a plain text telling them to switch to an HTTPS connection has exactly the same effect from a security point of view, except the later is more annoying.

You can even use something like a HSTS header, that really helps security (in the sense that the user would only be vulnerable the first time they use an insecure channel, not all the time), but regardless of that, if the user is already making a HTTP request, refusing to serve it (even as a simple 301 redirect to https) is plain useless.

Marcus Danillo Nunes
Advanced JavaScript and CSS Developer
Drupal Core, Contrib and Translation Contributor
Certified to Rock #3

Contact:
drupal@danillonunes.net
http://danillonunes.net/en/contact

John Morahan’s picture

I've updated that point to be more accurate.

mcmacerson’s picture

If you're running strictly HTTPS (best method) and you're still banging your head against the wall because all your sublinks are still HTTP, timdaman (above) has the solution https://www.drupal.org/https-information#comment-5922430

$_SERVER['HTTPS'] = 'On';

... in sites/default/settings.php

Thanks timdaman! And also thanks:
https://www.lullabot.com/blog/article/setting-ssl-offloading-termination...

No other Drupal configuration settings are needed if you're running only HTTPS.

stevep’s picture

I've confirmed that adding $_SERVER['HTTPS'] = 'On'; (in sites/default/settings.php) is a solution, but ... (See below)

Previously I had added to the .htaccess file (following advice http://drupal.stackexchange.com/questions/24072/how-to-simply-make-the-w...)

# Redirect to HTTPS
RewriteCond %{HTTPS} off
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

But that code was overwritten when doing updates via drush, setting the site back to standard http

That said, it seems browser cache needs to be cleared if relying on the change in settings.php, which suggests it is not as optimal as the .htaccess method which redirects to https irrespective?

ItangSanjana’s picture

edited..

Jorgee’s picture

It didnt work in Drupal 8. I had to put $_SERVER['HTTPS'] = 'on'; in update.php and index.php

edvanleeuwen’s picture

I am still having troubles directing old (i.e. http) links to the secure pages. E.g.:

https://example.com/foo
-> works
http://example/com/foo
-> redirects to https://example/index.php

I have tried inserting the AllowOverride and using the SERVER-setting; both to no avail.

Any other suggestions?

Best regards,

Ed

edvanleeuwen’s picture

I had problems forcing https. It turned out that stripping the www. part was the culprit, causing every non-SSL call to be directed to index.php.

When I reverted to routing everything to www., this issue was solved.

Best regards,

Ed

walkerasindave’s picture

I have registered and set up certificates for all my subdomains. I have set my server to redirect all http requests to https for all of my subdomains. Everything is working ok except for the form actions on every form on the site.

Every form on the site has an action of http... therefore causing unsecure popup. This is affecting all forms from login forms, edit forms, configuration forms, webforms, everything.

Please help.

ericwenger’s picture

As this article says, you can redirect (using .htaccess) all www & non-www to non-www https with:

(Drupal 7)

RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www.domainname\.com*
RewriteRule ^(.*)$ https://domainname.com/$1 [L,R=301]

But if you want to redirect (using .htaccess) all non-www & www to www https, use this:

(Drupal 7)

RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^domainname\.com*
RewriteRule ^(.*)$ https://www.domainname.com/$1 [L,R=301]
broadway’s picture

I struggled with this.
I'm making my whole site https.
www is my preferred form.

In my case the problem I was having was:
1) http://www.example.com transfered to https://www.example.com properly.
2) But http://example.com would not transform into https://www.example.com properly.

In my case I had to simply put the http to https code below that where the non-www to www transformation takes place.

#Standard Drupal code for non-www to www
RewriteCond %{HTTP_HOST} .
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ http%{ENV:protossl}://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

#The http to https code from above in this thread.
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

broadway

mpark’s picture

Hello, why this page isnt full secured? Browser writes me that the connection is not fully secured. But if I switch to admin page, connection (line) is green and full secured, where is a problem on this frontpage, please?

https://www.ucetnictvi-praha-4.cz/

John Morahan’s picture

There's a useful resource at https://www.whynopadlock.com/ that can be helpful in debugging this sort of thing. In your case it shows that you are referencing a number of insecure resources.

Some browsers will also provide you this information via their developer tools.

mpark’s picture

Thank you John, the url i very helpful for debugging.

scareyclott’s picture

I have tried all of these and some more but i still can get the whole site to all go through https is there anyone who can please help

If i use the following in this tester http://htaccess.madewithlove.be/ i get the desired result

RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www.skatexchange\.co.uk*
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R]

But once it is used on the site i get redirect error
'www.skatexchange.co.uk redirected you too many times.'

I am using Drupal 7 with a bootstrap theme on the host 123-reg

Incidentally if i use the solution their support gave (see below) i get a site with no theme or images ?

RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.skatexchange.co.uk/ [R,L]

Please can someone help or guide me with some questions for the 123-reg support about any server redirects that may affect it

Scott

mpark’s picture

hi, forget some advice from a hosting and try to use default Drupal .htaccess settings:

RewriteEngine on

  # Set "protossl" to "s" if we were accessed via https://.  This is used later
  # if you enable "www." stripping or enforcement, in order to ensure that
  # you don't bounce between http and https.
  RewriteRule ^ - [E=protossl]
  RewriteCond %{HTTPS} on
  RewriteRule ^ - [E=protossl:s]

  # Make sure Authorization HTTP header is available to PHP
  # even when running as CGI or FastCGI.
  RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

  # Block access to "hidden" directories whose names begin with a period. This
  # includes directories used by version control systems such as Subversion or
  # Git to store control files. Files whose names begin with a period, as well
  # as the control files used by CVS, are protected by the FilesMatch directive
  # above.
  #
  # NOTE: This only works when mod_rewrite is loaded. Without mod_rewrite, it is
  # not possible to block access to entire directories from .htaccess, because
  # <DirectoryMatch> is not allowed here.
  #
  # If you do not have mod_rewrite installed, you should remove these
  # directories from your webroot or otherwise protect them from being
  # downloaded.
  RewriteRule "(^|/)\." - [F]

  # If your site can be accessed both with and without the 'www.' prefix, you
  # can use one of the following settings to redirect users to your preferred
  # URL, either WITH or WITHOUT the 'www.' prefix. Choose ONLY one option:
  #
  # To redirect all users to access the site WITH the 'www.' prefix,
  # (http://example.com/... will be redirected to http://www.example.com/...)
  # uncomment the following:
   RewriteCond %{HTTP_HOST} .
   RewriteCond %{HTTP_HOST} !^www\. [NC]
   RewriteRule ^ http%{ENV:protossl}://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
scareyclott’s picture

Thanks, i will give this a go. Will this direct all to https:// secure? From the comments i thought this just added or removed the the www. bit

Scott

John Morahan’s picture

That .htaccess tester is a useful resource, but you need to use it correctly. In particular, for HTTPS redirects, check all four conditions: http and https, www and non-www. The results you presumably want are:

http://www.skatexchange.co.uk => https://skatexchange.co.uk
http://skatexchange.co.uk => https://skatexchange.co.uk
https://www.skatexchange.co.uk => https://skatexchange.co.uk
https://skatexchange.co.uk => no redirect

But what your rules actually yield is:

http://www.skatexchange.co.uk => https://www.skatexchange.co.uk
http://skatexchange.co.uk => https://skatexchange.co.uk
https://www.skatexchange.co.uk => https://www.skatexchange.co.uk
https://skatexchange.co.uk => no redirect

That third one is the cause of your infinite redirect loop (and the first one is not quite ideal either). The reason behind it is your use of %{HTTP_HOST} in the RewriteRule: this retains the www or non-www domain as provided by the original request. You should be able to fix it by explicitly naming the non-www domain in the RewriteRule.

jasom’s picture

I have added this 2 lines in .htaccess after Drupal base code:

#This is Drupal basic code
RewriteCond %{HTTP_HOST} .
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ http%{ENV:protossl}://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# Special 2 lines + explanation:
# http://stackoverflow.com/a/26920426
# If you are using CloudFlare or a similar CDN you will get an
# infinite loop error with the %{HTTPS} solutions provided here.
# If you're a CloudFlare user you'll need to use this:

RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

And it works finally :D

scareyclott’s picture

Thanks Jasom,

This solution doesn't seem to work for me.

I would however like to thank you for this TUT that has helped with this site
https://www.jasom.net/webform-is-submitted-send-email-to-the-current-nod...

Thanks Scott

scareyclott’s picture

Hi John,

Thanks
I do think this is the solution but i am still getting a redirect and i think it is now on the 4th one.
I changed it to this

RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www.skatexchange\.co.uk*
RewriteRule ^(.*)$ https://skatexchange.co.uk%{REQUEST_URI} [L,R]

the tester now gives me

http://www.skatexchange.co.uk => https://skatexchange.co.uk/
http://skatexchange.co.uk => https://skatexchange.co.uk/
https://www.skatexchange.co.uk => https://skatexchange.co.uk/
https://skatexchange.co.uk => https://skatexchange.co.uk/index.php - (think this is now the infinite redirect loop)

Any more ideas

Scott

John Morahan’s picture

Nothing in those three lines points to index.php - maybe it's some other part of your .htacess interfering?

scareyclott’s picture

Hi John,

Yes you are right. I am using the file that came with Drupal and I has a rule further down to redirect anything not referring directly to the file system to the index.php.
I am unsure if this can be disabled. I have attached the enabled rules of the file below if I can’t get it going this way I will have to try and set up the Secure Pages Module

# Various rewrite rules.
<IfModule mod_rewrite.c>
  RewriteEngine on
  
  #This works on the tester http://htaccess.madewithlove.be/ but not on the actual site where it  
  #gives a infinite redirect loop 
  RewriteCond %{HTTPS} off [OR]
  RewriteCond %{HTTP_HOST} ^www.skatexchange\.co.uk*
  RewriteRule ^(.*)$ https://skatexchange.co.uk%{REQUEST_URI} [L,R]
  

  # Set "protossl" to "s" if we were accessed via https://.  This is used later
  # if you enable "www." stripping or enforcement, in order to ensure that
  # you don't bounce between http and https.
  RewriteRule ^ - [E=protossl]
  RewriteCond %{HTTPS} on
  RewriteRule ^ - [E=protossl:s]

  # Make sure Authorization HTTP header is available to PHP
  # even when running as CGI or FastCGI.
  RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

  # If you do not have mod_rewrite installed, you should remove these
  # directories from your webroot or otherwise protect them from being
  # downloaded.
  RewriteRule "(^|/)\." - [F]

  # Pass all requests not referring directly to files in the filesystem to
  # index.php. Clean URLs are handled in drupal_environment_initialize().
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_URI} !=/favicon.ico
  RewriteRule ^ index.php [L]

  # Rules to correctly serve gzip compressed CSS and JS files.
  # Requires both mod_rewrite and mod_headers to be enabled.
  <IfModule mod_headers.c>
    # Serve gzip compressed CSS files if they exist and the client accepts gzip.
    RewriteCond %{HTTP:Accept-encoding} gzip
    RewriteCond %{REQUEST_FILENAME}\.gz -s
    RewriteRule ^(.*)\.css $1\.css\.gz [QSA]

    # Serve gzip compressed JS files if they exist and the client accepts gzip.
    RewriteCond %{HTTP:Accept-encoding} gzip
    RewriteCond %{REQUEST_FILENAME}\.gz -s
    RewriteRule ^(.*)\.js $1\.js\.gz [QSA]

    # Serve correct content types, and prevent mod_deflate double gzip.
    RewriteRule \.css\.gz$ - [T=text/css,E=no-gzip:1]
    RewriteRule \.js\.gz$ - [T=text/javascript,E=no-gzip:1]


Scott

sk2013’s picture

Hello everyone,

It would be great and nice if some one could help with an add on code to drupal .htaccess file for this scenario:

All non http urls like http://domain.com , www.domain.com and https urls like https://domain.com and https://www.domain.com should always direct to https://www.domain.com

Your help is highly appreciated.

Thanks,

sk2013’s picture

Put this code in start of the .htaccess file:

RewriteEngine On

RewriteCond %{HTTP_HOST} !^www. [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

jaesperanza’s picture

This worked. Thanks for making it simple, mate!

FareedAg’s picture

I have two sites with domains sitea.com and siteb.com hosted in Server A with domain name abc.com, after I added the lines of code in the .htaccess of sitea.com for the https, the sitea.com redirects to domain abc.com. What is missing here please?

This is the code i used
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www.domainname\.com*
RewriteRule ^(.*)$ https://domainname.com/$1 [L,R=301]

Also, an anonymous user has been running cron on my site, literally hacking through it because a content was changed. Any security advice will be appreciated.

panditvarun20’s picture

I want to know what should I use if i am not using securepages module for secure connection. I am a newbie so please correct me

Thanks
Varun

Varun Kr Pandey

scareyclott’s picture

You can configure your .htaccess file as in tbe discussion above. I think the secure pages module just gives a user friendly intrface to do this

sprite’s picture


RewriteEngine on

# the following 6 directives force all requests to https

RewriteCond %{HTTP_HOST} ^website\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.website.com/$1 [R,L]

RewriteCond %{HTTP_HOST} ^www\.website\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.website.com/$1 [R,L]

----

There may be more efficient methods, but the one above appears to work and to work with and without the www prepended.

spritefully yours
Technical assistance provided to the Drupal community on my own time ...
Thank yous appreciated ...