Moving from HTTPS to HTTP - wordpress

My WordPress client no longer wants SSL encryption. Currently, I have the following in .htaccess to force SSL encryption:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
Previous visitors' browsers will automatically try for HTTPS because of the 301 I believe. How can I move to HTTP (unsecure) without having previous visitors run into issues?

I can't think of any good reason why you would want to do this; especially in 2017. There are a number of factors against you:
You need to still keep a valid SSL cert in place in order to redirect from HTTPS back to HTTP. You would need to do this for all the inbound links to https, search engine indexes, bookmarks, etc. As mentioned in this other question, without a valid SSL cert in place, the user sees a browser warning before the request even reaches your site. (If you need to keep the SSL cert in place then why not use it properly?)
Any browser that has cached the HTTP to HTTPS 301 redirect will naturally be redirected to the HTTPS site. Without a valid SSL cert they will see a browser warning. With a valid SSL cert the user will be redirected back to HTTP (but this also depends on whether the page/resources are also cached). However, this can result in a (partial) redirect loop - depending on the browser, you might get a momentary warning (ERR_TOO_MANY_REDIRECTS) before the browser resolves the conflict. Some browsers may not resolve the conflict, so the user may be left looking at an error until they manually clear their browser cache.
To minimise this redirection issue, reduce all caching to a bare minimum and change any essential redirects to 302 (temporary) far in advance of moving back to HTTP. Neither of which is ideal.
Google Chrome currently warns users when they are entering username/password and/or payment information over an insecure (HTTP) connection. This will naturally include logging into WordPress. You get a "Not Secure" message in the browsers address bar. Google plan to extend this behaviour to Incognito mode (all sites) and eventually to everything. This will make it very difficult for any site to stay on plain old HTTP.
See the following related question on the Pro Webmasters stack:
Are there other options besides HTTPS for securing a website to avoid text input warnings in Chrome?
And Google's Security Blog post announcing the proposed changes:
Google Security Blog - Moving towards a more secure web -
September 8, 2016
With the introduction of free/automated CA's like Let's Encrypt it's not so much a money-thing these days if you simply want to enable encryption.
So, I think educating your client would be the better option.

Related

redirect all sub url to primary url

I have a wordpress site running on apache. I need to redirect domain.com/examplepage/* to domain.com/examplepage
so as an example
domain.com/examplepage/randomstring/randomstring
world go to
domain.com/examplepage
I've tried to google how to do this but cant find a way. I'm sure it's because I just don't know how to search for the correct thing. I'm willing to use wordpress plugin, .htaccess, or apache config. Whatever works.
Well, you can see many, many answers to this here on SO. Did you check the "Related" section on the right hand side here?
Anyway, here is what you are probably looking for:
RewriteEngine on
RewriteRule ^/?examplepage/.+ /examplepage [END]
The above implements an internal rewrite. In case you really want an external redirection instead this would be the variant:
RewriteEngine on
RewriteRule ^/?examplepage/.+ /examplepage [R=301]
It is a good idea to start out with a 302 temporary redirection and only change that to a 301 permanent redirection later, once you are certain everything is correctly set up. That prevents caching issues while trying things out...
In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup, certainly you will need to add another rewriting condition to break an endless rewriting loop.
This implementation will work likewise in the http servers host configuration or inside a distributed configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a distributed configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.
And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using distributed configuration files (".htaccess"). Those distributed configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).

How do I block a website's IP address using images from my sub domain (images.domainname.com)?

I have a .htaccess file in the images.domainname.com subdomain. I have tried
order allow,deny
deny from "id address i want to block"
allow from all
but this didn't work...
Indeed, if the website is simply embedding the images with HTML, the IP address of the website won't show as the requester. Your server will get the IP address of the visitor on the copying website.
However, .htaccess rules can be used to check that the HTTP referrer doesn't come from badwebsite.com. A word of warning here – not all browsers send a HTTP referrer. Therefore, it is important to remember that the referrer might be blank.
The following will deny access to jpg, jpeg, png and gif files if the referrer is not empty and not from yourdomain.com. Replace yourdomain.com with your actual domain in the following code.
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?yourdomain.com [NC]
RewriteRule \.(jpg|jpeg|png|gif)$ - [NC,F,L]
One disadvantage of this: if people find an image from Google and click through, they will be blocked as well if their browser sends a referrer. This might not be a big deal but would require some testing on your part to determine whether or not you're happy with the behavior.
Alternatively, you could:
Contact the site owner about the issue. Give him a handful of days to respond.
Rename your images. This entails updating the references to the images in your HTML etc., so this may not be possible depending on the size of your site.
As a less serious remark: if the owner fails to reply after a sensible time, don't forget that you basically control a part of his website. ;)
You could use images with huge dimensions instead and possibly break the design or upload an image with a polite request to remove the embedded images. This is not recommendable in any professional context, of course, and I would really, really urge that you keep things clean; you don't want to be held responsible for displaying inappropriate content to unsuspecting visitors, ethically as well as legally.

strange 401 error appears for some urls when using .htaccess to redirect http to https

OK, here is the 7th day of unsuccessfull attempt to find an answer why 401 error appears...
Now,
.htaccess in the root folder contains the only 3 strings (was simplified) and there are NO more .htaccess files in the project:
RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
So, it redirects all requests to be https. It works fine for any urls, even for /administration directory.
So,
http://mydomain.com
becomes
https://mydomain.com
If https://mydomain.com was entered, there are no redirections.
http://mydomain.com/administration/index.php
becomes
https://mydomain.com/administration/index.php
If https://mydomain.com/administration/index.php was entered, there are no redirections.
That's clear, and the problem is below.
I want /administration directory to be password protected. My Shared Hosting Control Panel allows to protect directories without manual creating of .htaccess and .htpasswd (you choose a directory to protect, create username and password, and .htaccess and .htpasswd are created automatically). So, .htaccess appears in the /administration folder. .htpasswd appears somewhere else, the path to .htpasswd is correct, and everything looks correct (it works the same way as to create it manually). So, there are 2 .htaccess files in the project, one in the root directory and one in the /administration directory (with .htpasswd at the directory .htaccess knows where it is).
Once the password is created,
the results are:
You enter:
https://mydomain.com/administration/index.php
Then it asks to enter a password.
If you enter it correctly,
https://mydomain.com/administration/index.php is displayed.
The result: works perfect.
But, if you enter
http://mydomain.com/administration/index.php (yes, http, without S)
then instead of redirecting to the same,but https page,
it redirects to
https://mydomain.com/401.shtml (starts with httpS)
by unknown reason and even does NOT ask a password. Why?
I've contacted a customer support regarding this question and they are sure the problem is in .htaccess file, and they do not fix .htaccess files (that's clear, they do not, I don't mind).
Why does this happen?
Did I forget to put some flags, or some options to change default settings in the .htaccess file?
P.S.Creating .htaccess and .htpasswd manually (not from hosting Control Panel) for the folder /administration causes the same 401 error in case if not https, but http was entered.
And the problem appears with URLs to /administration directory only.
Thank you.
Try using this instead. Not the L and R flag.
RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Also clear your browsers cache first, to remove the old incorrect redirect.
If that doesn't work try using this.
RewriteCond %{HTTPS} !on
RewriteCond %{THE_REQUEST} ^(GET|HEAD)\ ([^\ ]+)
RewriteRule ^ https://%{HTTP_HOST}%2 [L,R=301]
I feel a bit bad about writing it, as it seems kind of hackish in my view.
EDIT
Seems the 2nd option fixed the problem. So here is the explanation as to why it works.
The authentication module is executed before the rewrite module. Because the username and password is not send when first requesting the page, the authentication module internally 'rewrites' the request url to the 401 page's url. After this mod_rewrite comes and %{THE_REQUEST} now contains 401.shtml instead of the original url. So the resulting redirect contains the 401.shtml, and not the url you want.
The get to the original (not 'rewritten') url, you need to extract it from %{THE_REQUEST}. THE_REQUEST is in the form [requestmethod] [url] HTTP[versionnumber]. The RewriteCond extracts just the middle part ([url]).
For completeness I added the [L,R=301] flags to the second solution.
I think I found an even better solution to this!
Just add this to your .htaccess
ErrorDocument 401 "Unauthorized"
Solution found at:
http://forum.kohanaframework.org/discussion/8934/solved-for-reall-this-time-p-htaccess-folder-password-protection/
-- EDIT
I eventually found the root cause of the issue was ModSecurity flagging my POST data (script and iframe tags cause issues). It would try to return a 401/403 but couldn't find the default error document because ModSecurity had made my htaccess go haywire.
Using ErrorDocument 401 "Unauthorized" bypassed the missing error document problem but did nothing to address the root cause.
For this I ended up using javascript to add 'salt' to anything which was neither whitespace nor a word character...
$("form").submit(function(event) {
$("textarea,[type=text]").each(function() {
$(this).val($(this).val().replace(/([^\s\w])/g, "foobar$1salt"));
});
});
then PHP to strip the salt again...
function stripSalt($value) {
if (is_array($value)) $value = array_map('stripSalt', $value);
else $value = preg_replace("/(?:foobar)+(.)(?:salt)+/", "$1", $value);
return $value;
}
$_POST = stripSalt($_POST);
Very, Very, Very Important Note:
Do not use "foobar$1salt" otherwise this post has just shown hackers how to bypass your ModSecurity!
Regex Notes:
I thought it may be worth mentioning what's going on here...
(?:foobar)+ = match first half of salt one or more times but don't store this as a matched group;
(.) = match any character and store this as the first and only group (accessible via $1);
(?:salt)+ = match second half of salt one or more times but don't store this as a matched group.
It's important to match the salt multiple times per character because if you've hit submit and then you use the back button you will go back to the form with all the salt still in there. Hit submit again and more salt gets added. This can happen again and again until you end up with something like:
foobarfoobarfoobarfoobar>saltsaltsaltsalt
I was not satisfied with the solutions above so I came up with another one:
In a modern web server configuration we should redirect all traffic to HTTPS so the user can not reach any content without HTTPS. After the user's browsing our content with HTTPS we can use authentication. With this in mind we can wrap the authentication directive in an If directive:
<If "%{HTTPS} == 'on'">
AuthType Basic
...
</If>
You can leave and use Rewrite directives as you like.
With this solution:
you must not change ErrorDocument as suggested by Hoogs
you must not extract path from THE_REQUEST in a hackish way as suggested by Gerben
This is the type of thing is that is a bit tricky to troubleshoot on Apache without the box right in front of you, but I what I think is happening is that your rewrite directive is being processed after path resolution, and it's the path resolution that has the password requirement.
Backing up a bit, the way a URL is resolved in Apache is that the request comes in and gets handed from module to module, kind of like a bucket brigade. Each module does its own thing....some modules do content negotiation, some translate URLs to file paths, some check authentication, one of them is mod_rewrite ...
One place where you see this in the configuration is actually that there is both a Location directive and a Directory directive which seem the same in most respects, but they are different because Locations talk about URLs and Directories talk about filesystem paths.
Anyhow, my guess is that going down the bucket brigade, Apache figures out that it needs a password to access that content before it figures out that it needs to redirect to HTTPS. (mod_rewrite is kind of a crazy module and it can mess with all kinds of things in surprising ways..it can do path translation, bits and pieces of rewrite, make subrequests, and a bunch of other nutty things).
There are few ways you can fix this that I can think of.
Change your directory root in the vhosts container for the http site so that it can't find the passworded file (this would be my approach)
Change your module load order so that mod_rewrite happens earlier in the chain (may have unexpected consequences)
Use setenvif
That last one needs more explanation. Remember the bucket brigade I told you about? Apache modules can also set environment variables, which are completely outside of the module->module->module->chain. You could, perhaps, set an environment variable if the site is not HTTPS. Then however you set up your access control could use the SetEnvIf directive to always allow access to the resource if it's set, BUT you have to make sure for sure that you're going to hit that rewrite rule.
As I said, my choice would #1 but sometimes people need to do crazy things, and Apache will let you.
My real-world SOP for https:// sites these days is that I just shoot all of my port 80 content over to a single vhost that can't serve any content at all. Then i mod_rewrite everything over https://... badda bing, badda boom, no http and no convoluted security risks.

Add SSL *only* to specific folder

I want to redirect users to the SSL secure server when they are accessing the 'Account' section of the site which will contain the forms for user profiles, settings, etc. However, I don't want users being able to access the rest of the site on the SSL server. Because of how I coded my templates, I have my paths set as <a href="/about"> as an example. If they are in the Account section and click a link to the About section, they would still be on the secure https: connection. Obviously, I can just hard code the links to link to the http:// server, but I'm looking for alternatives.
So far I have the following in my .htaccess and it is working, but I'm wondering if this more resource intensive than it needs to be? Is it better to hardcode links to any of the other 'non-account' sections, or is doing this via .htaccess a good way to go about it?
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond $1 ^(account) [NC]
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{HTTPS} on
RewriteCond $1 ^(about|terms|products) [NC]
RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Also, if I wanted to prevent the homepage from being accessed via https:// how would I go about adding that to my .htaccess file?
I would actually suggest to avoid to use rewrite rules for this.
The problem with rewrite rules that turn http requests into https requests is that they're in fact redirections. This means that for every http request that is to be turned into an https request, the browser is first going to make the full http request (including content, cookies, except secure ones), get the redirection code from the server and then make the request again to the https re-written URL.
Although this is convenient, if you rely on this instead of making sure the links on your site that are intended to be to https sections are indeed using https, it will make it hard to detect when those link are incorrectly redirecting to the http variant.
The typical consequences are:
mixed content warnings if you embed something using an http linked later turned automatically and transparently into https, which is a bad thing; and
possible leakage of data.
Instead, I would suggest that you don't use automatic rewrite/redirects and make sure the sections that are meant to be available via HTTPS only are not available at all on the plain HTTP variant (i.e. http://yourhost/account should return 404s): this will at least force you to notice when you've incorrectly linked and help you spot where you could have a security issue. Ultimately, although they share the same host name, an http site and and https site can have two distinct URL spaces: it's not a bad thing in this context.
The only case I see where rewrites from http to https are really useful are when you want to make sure the user's entry point to your site is redirected.
Rewrites from https to http don't present this problem of course.

Catch SSL cert request error so as to redirect to the correct site

We are using IIS 6 and ASP.Net, When users make secure page requests using
https://somesite.com/securePage.aspx
the user gets an error:
Error code: ssl error bad cert domain
The certificate was issued to www.somesite.com and indicates that somesite.com uses an invalid security certificate.
I was hoping to be able to catch the request in the Application BeginRequest event but the SSL error occurs before this. In order to invoke the Application BeginRequest event the user needs to click through the certificate error message. Is it possible to redirect in code or does this fix need to occur within IIS?
The only solution is to include the second domain in the certificate with a SubjectAlternativeName. Some certificate authorities will allow you to do this without extra cost.
Everything else would only happen after the ssl connection is established and therefor after the error is encountered by the user.
With HTTPS the ssl connection is negotiated before any of the HTTP headers are sent to the server, including the Host:-header that tells the server for which virtual host the request is actually intended.
I was able to solve this problem using IIS's rewrite feature. Turned out to be really easy to fix and we didn't have to purchase a new cert.
HOP is correct with his answer. Owen also if we had the luxury of using IIS 7 as Rewrite rules similar to the mod_rewrite rule of Apache is now possible from within IIS. After further investigation today together with our Network Admins and our SSL Cert provider applying a SAN to our Certificate is quite possible and at no charge.However due to political issues within the ORG it was decided that DEV (my group) institute a redirect to the registered domain within the Application BeginRequest event. For each request we will check that the URL points to our FQDN. If the request is made to the 'Short Name' then we will point it to the FQDN always by appending the www to the short name that will be returned by the context.Host method.
No doubt this will increase chattiness etc.!
I did some testing on this on one of my servers and here is what I found.
We have a UCC certificate which will work for 5 domains. My 5 domains are
master mydomain.com
sub alt names:
mysite.com
myweb.com
thissite.com
www.thissite.com
The reason it is set up like that is because I didn't quite understand that it wanted www. when I made it.
So,
https://mydomain.com - works
https://www.mydomain.com - works
https://www.mysite.com - ERROR
https://mysite.com - works
https://thissite.com - works
https://www.thissite.com - works.
If you have a UCC cert (it seems you do) add a subject alternate name with the www on the domain in question. It will then work for both.
I went through all the steps of trying to redirect with .htaccess and server side scripting. But, hop is right, it will not do anything if you dont fix the cert.
You will likely have to drop a domain when you rekey your cert. Just remember which one you dropped and get a new cert for that one. I will forever and always REFUSE to buy UCC certs from now on. More problems than they are worth. 1 domain = 1 cert.
If your domain is making money then its worth the money, if your not making any money - do you really need the cert?
Intresting. I have never observed this behavior in any site until I saw this question. Even google has this problem. The url below gives the bad cert error
https://google.com/accounts/
Btw, Most of the sites has a subdomain to which they protect it with a certificate. One vote up for the question.
In Apache this is usually done with mod_rewrite:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]
Google for "rewrite URL IIS", you'll find some equivalents for IIS.

Resources