Hosting Autopsy / The forced HTTPS that locked out the admin

The forced HTTPS that locked out the admin

HOSTING AUTOPSY

6 min read · 1,387 words

This is a composite case written by the editors. It is built from patterns that come up often in support work and is not the account of a particular named person or company.

A site owner installed a plugin that forces HTTPS. He also had a server rule doing the same thing, and his hosting company's proxy was passing requests along over plain HTTP.

The result was a redirect loop that made the whole site, including the login page, unreachable. He could not log in to disable the plugin.

Renaming the plugin's folder through the file manager restored access, and he then removed the duplicate rules and set the site address properly. The owner ran a small publishing site on a popular content management system; this account is a composite, and the details are chosen to show the mechanism, which turns up on shared hosting, VPS plans and managed platforms alike.

Three things that each wanted HTTPS

The site had been on HTTP for years. When the certificate arrived through the hosting control panel, the owner did what most people do next: he went looking for a way to make everybody use it. He found three, and used all of them over the course of a weekend.

Any one of the three, configured correctly, would have worked. Together they produced an argument. The trouble was not that they disagreed about the goal, but that each decided whether a request was secure by looking at something different.

BrowserHost's proxydecrypts HTTPSWeb serversees plain HTTPhttps://http://"Not secure, go to https://" and round again
The proxy hides the visitor's HTTPS from the web server, so the server keeps asking for it.

How a redirect loop actually forms

Many hosting setups put a proxy or load balancer in front of the web server. The visitor's browser makes an encrypted connection to the proxy. The proxy decrypts it and passes the request to the web server over plain HTTP on a private connection. This is normal and efficient, and it means the certificate lives in one place.

The web server, however, only sees the inner leg. From where it sits, every request is plain HTTP. The redirect rule asks "is this request on HTTPS?", receives the answer no, and replies with a redirect to the https address. The browser follows it, the proxy decrypts it again, forwards it as HTTP again, and the rule says no again.

After about twenty round trips, the browser gives up and shows a message such as "This page isn't redirecting properly" or the error code ERR_TOO_MANY_REDIRECTS. The server did exactly what it was told; it just never learned that the visitor was already secure.

Proxies normally pass the original scheme in a header, usually X-Forwarded-Proto: https. A rule that checks only the server's own idea of HTTPS ignores it. And a plugin that checks the header while a rule beside it does not will produce a loop only for the pages one of them handles, which is why the symptoms can look patchy.

Why the admin panel went with it

The loop did not affect only the public pages. The login address, /wp-login.php on this platform, went through the same plugin and the same rules. Every address under the site produced a redirect. The owner had no way into the dashboard, and the plugin that was causing the damage could be switched off only from the dashboard.

This is the typical shape of a self-inflicted lockout: the control that would undo the change lives behind the thing you broke. It deserves attention before the change, not after.

The owner tried the obvious things first. He cleared cookies, which does nothing for a server-side loop. He tried another browser, then his phone, then a different network, all with the same error. Someone on a forum suggested waiting for the cache to clear. It did not.

Browsers cache permanent (301) redirects aggressively. After you fix a loop, test in a private window or with curl, or you may see the old behaviour for a while even though the server is right.

Getting back in without the dashboard

The file manager in the hosting panel does not depend on the website, so it still worked. The owner opened the site's folder, went into wp-content/plugins/, and renamed the HTTPS plugin's folder by adding -off to the end of its name.

The effect is immediate. The application scans the plugins folder for plugin names it expects; with the folder renamed, the plugin is not found, and WordPress deactivates it. The plugin's redirect disappeared, and the login page loaded within seconds.

That alone left two sources of redirects, the .htaccess rule and the panel setting, and the site was still partly confused, so the owner worked through them in order:

  1. Log in and check Settings, General. Both the WordPress Address and the Site Address should start with https://. If they cannot be changed from the dashboard, set WP_HOME and WP_SITEURL in wp-config.php.
  2. Remove the duplicated redirect from .htaccess or make it proxy-aware, as shown below.
  3. Turn off whichever of the panel setting and the plugin he did not want to keep, leaving one.

Making the rule proxy-aware

If a proxy sits in front, the server rule should trust the header it sends. A rule that works both with and without a proxy looks like this:

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

The rule redirects only if both tests say the request is insecure. Application code needs the same awareness. In WordPress, a few lines near the top of wp-config.php tell the software that the request is secure when the proxy says so:

if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
    $_SERVER['HTTPS'] = 'on';
}

Only do this if you know the proxy sets the header and strips any value sent by visitors. On shared hosting your provider's documentation will say which header is used. Better still, pick a single owner for the redirect, the proxy or the web server, and remove the rest.

BeforePanel "force HTTPS".htaccess rulePlugin redirectAfterOne rule, proxy-awarePlugin: offPanel setting: off
Three overlapping redirectors became one that is responsible and understood.

Why three redirectors made it worse

With a single redirect rule that misjudged the request, the site would have looped just the same, so the duplication was not the root cause. It did make the diagnosis slower. Each layer produced the same symptom, and removing one had no visible effect because the other two still looped. The owner disabled the panel setting first, saw no change, and concluded that the setting was irrelevant. It was not; it was merely not the only offender.

There was a second, quieter cost. The panel setting and the plugin sometimes disagreed about www. One redirected to the version with www, the other to the version without. A visitor on the bare address could bounce between the two forms, crossing HTTP and HTTPS each time, and the loop was only partly about the scheme. When more than one component rewrites addresses, you cannot reason about the result by reading any one of them.

The practical lesson is to change one thing at a time and test with curl between changes. A browser hides the hops; curl lists every one.

Smaller questions

Is a plugin better than a server rule?

The server rule is faster and works before the application loads. A plugin is easier to manage but depends on the application. Pick one.

Why only some visitors had trouble?

Cached redirects and different entry addresses, with and without www, hit different rules.

Can I fix this without file access at all?

Some hosts provide a plugin-disabling button or a recovery mode in the panel. Ask your provider before you need it.

Does the loop affect search rankings?

If it lasted long enough for crawlers to notice, yes, so fix it quickly.

What would have caught it

PreviousThe staging site that emailed real customersNextThe upload folder that exceeded its quota in a night

More from Hosting Autopsy

Autopsy

The sale that started at the wrong hour

A retailer scheduled a flash sale for 9 a.m. The shop software was set to the store's local time. The...

Autopsy

The PHP upgrade that broke the checkout

A shop owner was told by the host that PHP 7.4 was reaching end of life and would be retired. She clicked the...

Autopsy

The mailbox that filled up and bounced the best client

A consultant used a single mailbox on her hosting plan for several years and never deleted anything....