186

How do you redirect HTTPS to HTTP?. That is, the opposite of what (seemingly) everyone teaches.

I have a server on HTTPS for which I paid an SSL certification for and a mirror for which I haven't and keep around for just for emergencies so it doesn't merit getting a certification for.

On my client's desktops I have SOME shortcuts which point to http://production_server and https://production_server (both work). However, I know that if my production server goes down, then DNS forwarding kicks in and those clients which have "https" on their shortcut will be staring at https://mirror_server (which doesn't work) and a big fat Internet Explorer 7 red screen of uneasyness for my company.

Unfortunately, I can't just switch this around at the client level. These users are very computer illiterate: and are very likely to freak out from seeing HTTPS "insecurity" errors (especially the way Firefox 3 and Internet Explorer 7 handle it nowadays: FULL STOP, kind of thankfully, but not helping me here LOL).

It's very easy to find Apache solutions for http->https redirection, but for the life of me I can't do the opposite.

Ideas?

shiser
  • 262
  • 1
  • 3
  • 13
mauriciopastrana
  • 5,010
  • 7
  • 35
  • 36
  • 5
    DO NOT do that ! HTTPS redirects from HTTP are extremely dangerous (and in fact will be blocked by all browsers soon due to abuse), espacially if this is node via silent HTTP status (but the same is true if this is done by javascript), unless either : - (1) there's a transient HTTPS parking page inviting users to fllow a link by clicking it actively; or : - (2) the HTTPS redirects to HTTP on exactly the **SAME** domain AND the redirects does not change the content type requested. Allowing it in browsers has allowed lot of malwares to pass isolation. Such redirects are very deceptive. – verdy_p Oct 04 '18 at 18:16
  • 7
    This looks like an internal site, where the OP knows whats going on with it, and thus not dangerous... If this was a web facing server, I'd agree with you, but a internal, local only webserver, a redirect in this fashion would not be an issue. – Stese Nov 05 '18 at 09:30
  • @verdy_p I am working on HTTPS to HTTP 302 redirects, the case of captive portals. Can you point me to documentation that you are referring to? – jprusakova Feb 15 '19 at 19:11
  • For your captive portal, never ever perform any HTTPS to HTTP 302 redirect except if this is exactly to the same domain (not even a subdomain). And as there's a high risk of information disclosure, beware of session tokens and cookies passed transparently with the redirect ! You should know that HTTP targets can be tweaked and information taken by malware transparent proxies and even by malicious DNS: your custoer mayu not even know that yur HTTP-only target will be unreachable and will actually go to a blackhat! So never do that on HTTPS links that contain private session/cookies/requests. – verdy_p Feb 17 '19 at 12:13
  • Such HTTPS 302 redirect are always security hole in your HTTPS site. The huge risk is having sessions stolen and your authenticated users having their private accounts harvested. And in all case, NEVER do such redirects for loading javascripts, or active multimedia: this is an open door in the HTTPS "sandbox" realm. Really consider doing something the reverse: redirect HTTP to HTTPS (notably your main portal or static public pages that don't need private data/sessions/cookies) and use HTTPS for everelse. If you ever need to get from HTTPS to HTTP, use standard links (in distinct requests) – verdy_p Feb 17 '19 at 12:20

11 Answers11

139

This has not been tested but I think this should work using mod_rewrite

RewriteEngine On
RewriteCond %{HTTPS} on
RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI}
Gili
  • 86,244
  • 97
  • 390
  • 689
ejunker
  • 10,816
  • 11
  • 41
  • 41
  • 1
    How do I make it work (what do I have to change from this code to my domain to make this code work)? – Idrizi.A Jan 09 '13 at 18:59
  • 2
    Enve: Just add to your site's vhost_ssl.conf configuration (or .htaccess at the root of the site). Nothing needs to be changed it will dynamically use the same host name and url path. – Darren Felton Jan 31 '13 at 19:53
  • 2
    I think you might also want to catch query strings. I'm not sure, but I think the above snippet will not forward query strings from https to http. – Rustavore May 14 '13 at 22:22
  • 1
    Although this works, it appears wrong per Apache (http://httpd.apache.org/docs/current/rewrite/avoid.html) Looks like you are supposed to use mod alias instead. – Jackie Apr 10 '14 at 13:07
  • 14
    As pointed by Kieron below, this wouldn't work if the mirror server has no valid certificate. You would still see a big red warning because of invalid certificate. Once you start to use https, you are basically stuck with it. Be prepared to pay for it throughout the rest of your life. If you stop paying, people who bookmarked the https links will not be able to come through. – Stephen Cheng Sep 09 '14 at 16:47
  • Would it be possible to do this avoiding a Rewrite, per Apache's recommendation at http://httpd.apache.org/docs/current/rewrite/avoid.html ? – Gaia Sep 22 '14 at 20:26
  • @Gaia Here's the Redirect version per Apache's recommendation `Redirect "/" "http://domain_to_redirect_to.com/"` – Poly Bug Oct 20 '15 at 00:15
  • I need it but combined only with "dev." host for all my domains. In other words, for `https://www.*` I will keep SSL and for `https://dev.*` I need to go `http://dev.*` because I haven't SSL certificate and it is better for me to test without warnings. How to ? – Meloman May 23 '16 at 13:16
  • If I put this suggested solution in `.htaccess` placed in specific folder underneath `www` of apache & set `AllowOverride All` in default_site.conf would it work ? – Ciasto piekarz Jan 04 '17 at 14:02
  • 2
    Paying for the rest of your life? You can still use HTTPS but change your PKI provider and get new cheaper certificates. You'll still pay a few bucks yes, but the same is true for your domain name and your hosting! A PKI certificate is now NOT expensive compared to domain names, and is insignificant compared to hosting/bandwidth costs! – verdy_p Feb 17 '19 at 12:27
  • Note: if you want mirrors, create subdomains in your main domain, one subdomain per mirror, and buy a PKI certificate for each one, and instruct your mirrors to accept and handle requests for your subdomain. The same can be said if you use a commercial CDN (like Amazon): configure it to use your subdomain and only accept requests from your subdomain rather than the default CDN's subdomain: you'll keep the full control on what's happening. – verdy_p Feb 17 '19 at 12:30
79

Keep in mind that the Rewrite engine only kicks in once the HTTP request has been received - which means you would still need a certificate, in order for the client to set up the connection to send the request over!

However if the backup machine will appear to have the same hostname (as far as the client is concerned), then there should be no reason you can't use the same certificate as the main production machine.

Kieron
  • 11,588
  • 5
  • 34
  • 29
13

For those that are using a .conf file.

<VirtualHost *:443>
    ServerName domain.com
    RewriteEngine On
    RewriteCond %{HTTPS} on
    RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI}

    SSLEngine on
    SSLCertificateFile /etc/apache2/ssl/domain.crt
    SSLCertificateKeyFile /etc/apache2/ssl/domain.key
    SSLCACertificateFile /etc/apache2/ssl/domain.crt

</VirtualHost>
Rick
  • 12,606
  • 2
  • 43
  • 41
12

Based on ejunker's answer, this is the solution working for me, not on a single server but on a cloud enviroment

Options +FollowSymLinks
RewriteEngine On
RewriteCond %{ENV:HTTPS} on
RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
antoniom
  • 3,143
  • 1
  • 37
  • 53
  • Using 301 can be little dangerous. 301 means permenantly removed and I guess going from https to http is temporarly. See this accepted answer for what the cons will be for users https://stackoverflow.com/questions/1393280/http-redirect-301-permanent-vs-302-temporary – yusuf tezel Jul 22 '19 at 11:44
  • The 301/302 permanent/temporary distinction is only relevant to search engines. – matthewv789 Nov 29 '19 at 08:49
10

If none of the above solutions work for you (they did not for me) here is what worked on my server:

RewriteCond %{HTTPS} =on
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1 [L,R=301]
rg88
  • 20,742
  • 18
  • 76
  • 110
  • 6
    Often times, you won't want the `L,` (which means "Last rule"). If you are using wordpress or another CMS, the `L` flag may prevent the page request from being properly routed. Instead use: `RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1 [R=301]` – Rustavore May 14 '13 at 22:20
5

all the above did not work when i used cloudflare, this one worked for me:

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

and this one definitely works without proxies in the way:

RewriteCond %{HTTPS} on
RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
mikulabc
  • 111
  • 2
  • 7
3

It is better to avoid using mod_rewrite when you can.

In your case I would replace the Rewrite with this:

    <If "%{HTTPS} == 'on'" >
            Redirect permanent / http://production_server/
    </If>

The <If> directive is only available in Apache 2.4+ as per this blog here.

simhumileco
  • 31,877
  • 16
  • 137
  • 115
sys0dm1n
  • 819
  • 6
  • 13
3

this works for me.

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

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

be sure to listen to both ports 80 and 443.

jaxarroyo
  • 190
  • 2
  • 15
1

None of the answer works for me on Wordpress website but following works ( it's similar to other answers but have a little change)

RewriteEngine On
RewriteCond %{HTTPS} on
RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
Yuseferi
  • 7,931
  • 11
  • 67
  • 103
  • Do not use such rules blindly with all REQUEST_URI (this should not be used if there are any form data in the URI, or cookies/sessions IDs in the request metadata). Use it only for static public pages/images. Avoid it completely for javascripts or active components (notably scriptable video streams, or active PDF's unless they are digitally signed by you! It's still not possible to digitally sign javascripts, keep them on your secure domain only). – verdy_p Feb 17 '19 at 12:34
  • Note: some image formats are active and scriptable: beware about SVG for example. We've seen attacks on some HTTPS websites loading SVG images from HTTP (with site's 302 redirects), and harvested by malwares inserting scripts in SVG contents... Ideally browsers should isolate HTTP subcontents from HTTPS and place it in a sandbox (so CORS security restrictions should apply too, even if it's in the same domain name...) so "http://(domain)/..." and "https://(domain)/" are to be considered distinct domains for CORS (not the same origin) even if they are on the same TCP port number. – verdy_p Feb 17 '19 at 12:38
  • @verdy_p, what exactly do you mean by that "with site's 302 redirects"? You have to own the server-site first (or participant nodes on the TCP/IP level, like DNS servers, routers), to exploit those HTTP resource request, right? – Sz. May 15 '20 at 13:06
  • Not necessarily. HTTPS on a domain will be safe while HTTP on the same domain will not be (exploits do not require controling an IP or routers, or DNS servers even when using DNSSEC; exploits can just use IP spoofing, that cannot be safely detected without HTTPS on secure sessions). So I maintain that an HTTPS site must host images (even on the same domain) by not serving them with HTTP (it is even denied by default in some browsers that require an activation click or mask those unsafe images). Mixed HTTPS/HTTP must be banned: the site is attackable on its HTTP parts (e.g. track pixels). – verdy_p May 16 '20 at 16:15
0

If you are looking for an answer where you can redirect specific url/s to http then please update your htaccess like below

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond %{THE_REQUEST} !/(home/panel/videos|user/profile) [NC] # Multiple urls
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

RewriteCond %{HTTPS} on
RewriteCond %{THE_REQUEST} /(home/panel/videos|user/profile) [NC] # Multiple urls
RewriteRule ^ http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

It worked for me :)

Khan Sharukh
  • 1,151
  • 12
  • 21
-6

As far as I'm aware of a simple meta refresh also works without causing errors:

<meta http-equiv="refresh" content="0;URL='http://www.yourdomain.com/path'">
RobinUS2
  • 955
  • 6
  • 17
  • 14
    I wish down voters would be required to leave comments explaining the reasons for down votes. Personally, I would not choose this answer unless you as a developer did not have access to the server you were developing for but you did have access to the page. One problem, is that you'll have to hardcode every path on every page to get this to work. If you can assume that JavaScript is enabled for your important use cases, you'd be better off using JavaScript to change to http. The above answers are better because they do not require javascript since they happen at the server. – Rustavore May 14 '13 at 22:19
  • 2
    Simply: because htaccess is far better option than that. Also, it doesnt' will fix the problem to redirect the https protocol to http if you doesn't have a certificate. – midudev Jun 14 '13 at 08:30
  • 1
    The action should be processed by the server, not 'a' document it may serve. – albal Aug 03 '14 at 12:38
  • 1
    For this to work you'd need two versions of the page, or some way to prevent the refresh if you reached the page via http. Otherwise you've created a refresh loop: https://www.yourdomain.com/path -> http://www.yourdomain.com/path -> http://www.yourdomain.com/path -> ...etc. – Dave Burton Mar 01 '21 at 10:44