[security] How to redirect all HTTP requests to HTTPS

I'm trying to redirect all insecure HTTP requests on my site (e.g. http://www.example.com) to HTTPS (https://www.example.com). I'm using PHP btw. Can I do this in .htaccess?

This question is related to security http .htaccess redirect https

The answer is


I'd recommend with 301 redirect:

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

Using the following code in your .htaccess file automatically redirects visitors to the HTTPS version of your site:

RewriteEngine On

RewriteCond %{HTTPS} off

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

If you have an existing .htaccess file:

Do not duplicate RewriteEngine On.

Make sure the lines beginning RewriteCond and RewriteRule immediately follow the already-existing RewriteEngine On.


If you are using Apache, mod_rewrite is the easiest solution, and has a lot of documentation online how to do that. For example: http://www.askapache.com/htaccess/http-https-rewriterule-redirect.html


If you are in a situation where your cannot access the apache config directly for your site, which many hosted platforms are still restricted in this fashion, then I would actually recommend a two-step approach. The reason why Apache themselves document that you should use their configuration options first and foremost over the mod_rewrite for HTTP to HTTPS.

First, as mentioned above, you would setup your .htaccess mod_rewrite rule(s):

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Then, in your PHP file(s) (you need to do this where ever it would be appropriate for your situation, some sites will funnel all requests through a single PHP file, others serve various pages depending on their needs and the request being made):

<?php if ($_SERVER['HTTPS'] != 'on') { exit(1); } ?>

The above needs to run BEFORE any code that could potentially expose secure data in an unsecured environment. Thus your site uses automatic redirection via HTACCESS and mod_rewrite, while your script(s) ensure no output is provided when not accessed through HTTPS.

I guess most people don't think like this, and thus Apache recommends that you don't use this method where possible. However, it just takes an extra check on the development end to ensure your user's data is secure. Hopefully this helps someone else who might have to look into using non-recommended methods due to restrictions on our hosting services end.


I like this method of redirecting from http to https. Because I don't need to edit it for each site.

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]

This redirects all the URLs to https and www

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

This is the proper method of redirecting HTTP to HTTPS using .htaccess according to GoDaddy.com. The first line of code is self-explanatory. The second line of code checks to see if HTTPS is off, and if so it redirects HTTP to HTTPS by running the third line of code, otherwise the third line of code is ignored.

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

https://www.godaddy.com/help/redirect-http-to-https-automatically-8828


It works for me:

<IfModule mod_rewrite.c>
 RewriteEngine On
  RewriteCond %{HTTPS} !on
  RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>

and for example, http://server/foo?email=someone%40example.com redirects normally without any issues. The file .htaccess located in the website root folder (for example named public_html). It is possible to use RewriteCond %{SERVER_PORT} !^443$ instead RewriteCond %{HTTPS} !on


The best solution depends on your requirements. This is a summary of previously posted answers with some context added.

If you work with the Apache web server and can change its configuration, follow the Apache documentation:

<VirtualHost *:80>
    ServerName www.example.com
    Redirect "/" "https://www.example.com/"
</VirtualHost>

<VirtualHost *:443>
    ServerName www.example.com
    # ... SSL configuration goes here
</VirtualHost>

But you also asked if you can do it in a .htaccess file. In that case you can use Apache's RewriteEngine:

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L]

If everything is working fine and you want browsers to remember this redirect, you can declare it as permanent by changing the last line to:

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

But be careful if you may change your mind on this redirect. Browsers remember it for a very long time and won't check if it changed.

You may not need the first line RewriteEngine On depending on the webserver configuration.

If you look for a PHP solution, look at the $_SERVER array and the header function:

if (!$_SERVER['HTTPS']) {
    header("Location: https://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']); 
} 

I found a method to force all pages of my site redirect from http to analog of pages on https that work for me.

RewriteEngine On 
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Do everything that is explained above for redirection. Just add "HTTP Strict Transport Security" to your header. This will avoid man in the middle attack.

Edit your apache configuration file (/etc/apache2/sites-enabled/website.conf and /etc/apache2/httpd.conf for example) and add the following to your VirtualHost:

# Optionally load the headers module:
LoadModule headers_module modules/mod_headers.so

<VirtualHost 67.89.123.45:443>
    Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"
</VirtualHost>

https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security


Not only can you do this in your .htaccess file, you should be doing this period. You will also want to follow the steps here to get your site listed on the HSTS preload list after you implement this redirect so that any requests to the insecure http version of your website never make it past the user agent. Instead, the user agent checks the requested URI against a baked in list of https only websites and, if the requested URI is on that list, changes the protocol from http to https before transmitting the request to the server. Therefore, the insecure request never makes it out into the wild and never hits the server. Eventually when the internet changes over to https only the HSTS preload list will not be needed. Until then, every site should be using it.

In order to perform the redirect, we need to enable the rewrite engine and then redirect all traffic from the http port 80 to https.

RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://yourwebsite.tld/$1 [L,R=301]

Through .htaccess This will help.

RewriteEngine On


RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]

RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]

Also, Refer this for More Detail. How To Redirect Http To Https?


I found out that the best way for https and www on domain is

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

To redirect all http requests to https , you can use :

RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [NE,L,R]

If mod-rewrite isn't enabled and you are on apache 2.4, you can also use a Redirect inside if directive to redirect http requests to https .

Apache 2.4.

<if "%{HTTPS} !~ /on/">
Redirect / https://www.example.com/
</if>

This is the html redirect approach it works but not the best.

 <meta http-equiv="Refresh" content="0;URL=https://www.example.com" />

PHP approach

<?php
function redirectTohttps() {
    if ($_SERVER['HTTPS']!="on") {
        $redirect= "https://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
        header("Location:$redirect"); 
    } 
}
?>

.htaccess approch

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

copied from: www.letuslook.org


Unless you need mod_rewrite for other things, using Apache core IF directive is cleaner & faster:

<If "%{HTTPS} == 'off'">
Redirect permanent / https://yoursite.com/
</If>

You can add more conditions to the IF directive, such as ensure a single canonical domain without the www prefix:

<If "req('Host') != 'myonetruesite.com' || %{HTTPS} == 'off'">
Redirect permanent / https://myonetruesite.com/
</If>

There's a lot of familiarity inertia in using mod_rewrite for everything, but see if this works for you.

More info: https://httpd.apache.org/docs/2.4/mod/core.html#if

To see it in action (try without www. or https://, or with .net instead of .com): https://nohodental.com/ (a site I'm working on).


If you're using an Amazon Web Services Elastic Load Balancer which accepts https traffic and routes it to your server(s) with http, the correct way to redirect all http traffic to https is described here: https://aws.amazon.com/premiumsupport/knowledge-center/redirect-http-https-elb

Use the X-Forwarded-Proto header (contains http or https) which is always included in http requests from the load balancer, as described here: https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/x-forwarded-headers.html

In the httpd.conf file:

<VirtualHost *:80>

RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]

</VirtualHost>

Or in your root .htaccess file:

RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]

Bonus: it will not try to redirect http traffic on your local development machine.


As I was saying in this question, I'd suggest you avoid redirecting all HTTP requests to their HTTPS equivalent blindly, as it may cause you a false impression of security. Instead, you should probably redirect the "root" of your HTTP site to the root of your HTTPS site and link from there, only to HTTPS.

The problem is that if some link or form on the HTTPS site makes the client send a request to the HTTP site, its content will be visible, before the redirection.

For example, if one of your pages served over HTTPS has a form that says <form action="http://example.com/doSomething"> and sends some data that shouldn't be sent in clear, the browser will first send the full request (including entity, if it's a POST) to the HTTP site first. The redirection will be sent immediately to the browser and, since a large number of users disable or ignore the warnings, it's likely to be ignored.

Of course, the mistake of providing the links that should be to the HTTPS site but that end up being for the HTTP site may cause problems as soon as you get something listening on the HTTP port on the same IP address as your HTTPS site. However, I think keeping the two sites as a "mirror" only increases the chances of making mistakes, as you may tend to make the assumption that it will auto-correct itself by redirecting the user to HTTPS, whereas it's often too late. (There were similar discussions in this question.)


A different edge to this problem is when a Load Balancer comes into play.

The situation is as follows: - Traffic from browser to Load Balancer, and back, is (should be) HTTPS - Traffic between Load Balancer and actual WebServer is HTTP.

So, all server request variables in PHP or Apache show that the connection is just HTTP. And the HTTP and HTTPS directories on the Server are the same.

The RewriteCondition in the approved answer does not work. It gives either a loop or it just doesn't work.

Question is: How to get this working on a Load Balancer.

(Or is the Load Balancer configured wrong. Which is what I'm hoping for because then I can move the problem over to the WebHosting company :-) )


take this code to you .htaccess file Redirect HTTP to HTTPS automatically

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


Add the following code to the .htaccess file:

Options +SymLinksIfOwnerMatch
RewriteEngine On
RewriteCond %{SERVER_PORT} !=443
RewriteRule ^ https://[your domain name]%{REQUEST_URI} [R,L]

Where [your domain name] is your website's domain name.

You can also redirect specific folders off of your domain name by replacing the last line of the code above with:

RewriteRule ^ https://[your domain name]/[directory name]%{REQUEST_URI} [R,L]

 Redirect 301 / https://example.com/

(worked for me when none of the above answers worked)

Bonus:

ServerAlias www.example.com example.com

(fixed https://www.example.com not found)


If you want to do it from the tomcat server follow the below steps

In a standalone Apache Tomcat (8.5.x) HTTP Server, how can configure it so if a user types www.domain.com, they will be automatically forwarded to https(www.domain.com) site.

The 2 step method of including the following in your [Tomcat_base]/conf/web.xml before the closing tag

step 1: 
<security-constraint>
<web-resource-collection>
<web-resource-name>HTTPSOnly</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>

and setting the [Tomcat_base]/conf/server.xml connector settings:

step 2:
<Connector URIEncoding="utf-8" connectionTimeout="20000" port="80" protocol="HTTP/1.1" redirectPort="443"/>
<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true">
<SSLHostConfig>
<Certificate certificateKeystoreFile="[keystorelocation]" type="RSA" />
</SSLHostConfig>
</Connector>

Note: If you already did the https configuration and trying to redirect do step 1 only.


The Apache docs recommend against using a rewrite:

To redirect http URLs to https, do the following:

<VirtualHost *:80>
    ServerName www.example.com
    Redirect / https://www.example.com/
</VirtualHost>

<VirtualHost *:443>
    ServerName www.example.com
    # ... SSL configuration goes here
</VirtualHost>

This snippet should go into main server configuration file, not into .htaccess as asked in the question.

This article might have come up only after the question was asked and answered, but seems to be the current way to go.


Examples related to security

Monitoring the Full Disclosure mailinglist Two Page Login with Spring Security 3.2.x How to prevent a browser from storing passwords JWT authentication for ASP.NET Web API How to use a client certificate to authenticate and authorize in a Web API Disable-web-security in Chrome 48+ When you use 'badidea' or 'thisisunsafe' to bypass a Chrome certificate/HSTS error, does it only apply for the current site? How does Content Security Policy (CSP) work? How to prevent Screen Capture in Android Default SecurityProtocol in .NET 4.5

Examples related to http

Access blocked by CORS policy: Response to preflight request doesn't pass access control check Axios Delete request with body and headers? Read response headers from API response - Angular 5 + TypeScript Android 8: Cleartext HTTP traffic not permitted Angular 4 HttpClient Query Parameters Load json from local file with http.get() in angular 2 Angular 2: How to access an HTTP response body? What is HTTP "Host" header? Golang read request body Angular 2 - Checking for server errors from subscribe

Examples related to .htaccess

Use .htaccess to redirect HTTP to HTTPs Getting a 500 Internal Server Error on Laravel 5+ Ubuntu 14.04 Server unable to read htaccess file, denying access to be safe Laravel 5 – Remove Public from URL Laravel 5 not finding css files How can I fix the 'Missing Cross-Origin Resource Sharing (CORS) Response Header' webfont issue? How Can I Remove “public/index.php” in the URL Generated Laravel? Apache 2.4 - Request exceeded the limit of 10 internal redirects due to probable configuration error Forbidden You don't have permission to access / on this server Htaccess: add/remove trailing slash from URL

Examples related to redirect

React-Router External link Laravel 5.4 redirection to custom url after login How to redirect to another page in node.js How to redirect to an external URL in Angular2? How to redirect to a route in laravel 5 by using href tag if I'm not using blade or any template? Use .htaccess to redirect HTTP to HTTPs How to redirect back to form with input - Laravel 5 Using $window or $location to Redirect in AngularJS yii2 redirect in controller action does not work? Python Requests library redirect new url

Examples related to https

What's the net::ERR_HTTP2_PROTOCOL_ERROR about? Requests (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available.") Error in PyCharm requesting website Android 8: Cleartext HTTP traffic not permitted ssl.SSLError: tlsv1 alert protocol version Invalid self signed SSL cert - "Subject Alternative Name Missing" How do I make a https post in Node Js without any third party module? Page loaded over HTTPS but requested an insecure XMLHttpRequest endpoint How to force Laravel Project to use HTTPS for all routes? Could not create SSL/TLS secure channel, despite setting ServerCertificateValidationCallback Use .htaccess to redirect HTTP to HTTPs