Logging out of HTTP Basic Authentication in Firefox

March 9, 2020

We make significant use of HTTP Basic Authentication in our local web servers, because if you use Apache it's a nice simple way of putting arbitrary things behind password protection. It's not the most user-friendly thing these days and it's probably not what you want if you also need to handle things like user registration and password resets, but in our environment all of those are handled separately. However, it does have one little drawback, which is logging out.

Normal user web authentication schemes are pretty much all implemented with browser cookies and often a backend session database. This means that 'logging out' is a matter of removing the cookies, marking the session as logged out, or both at once. Logging you out is a straightforward and unobtrusive thing for a website to do (and it can even do so passively), and even if a website doesn't support logging out you can do it yourself by scrubbing the site's cookies (and Firefox is making it increasingly easy to do that).

There is no equivalent of this for HTTP Basic Authentication. The browser magically remembers the authentication information for as long as its running, there's no way for the website to gracefully signal to the browser that the information should be discarded, and Firefox doesn't expose any convenient controls for it to the user (Firefox doesn't even seem to consider HTTP Basic Authenticaion to be 'cookies and site data' that it will let you clear). Traditionally the only way to 'log out' from HTTP Basic Authentication was to quit out of your entire browser session, which is a bit obtrusive in these days of tons of windows, tabs, and established sessions with other websites.

Recently I learned that you can do better, although it's a bit obtrusive and not particularly user-friendly. The magic trick is that you can overwrite Firefox's remembered HTTP Basic Authentication user and password with a new, invalid pair by using a URL with embedded credentials. If you're currently authenticated to https://example.com/app, you can destroy that and effectively log out by trying to access 'https://bad:bad@example.com/app'. The drawback is that you'll get an authentication challenge popup that you have to dismiss.

(Chrome apparently no longer supports specifying credentials in URLs this way, so this trick won't work in it. Hopefully Firefox is not going to go the same way, at least not before it adds some sort of UI to let you discard HTTP Basic Authentication credentials yourself. MDN does describe this as deprecated in the MDN page on HTTP authentication, so it may be going away someday even in Firefox.)

You can definitely enter such an URL by hand (or modify the existing URL of the page in the URL bar to insert the 'bad@bad:' credentials bit) and it works. I believe that Firefox will still support links on web pages that have credentials embedded in them, so you could put a 'log out by trying to use this' link on your index page, but I haven't tested it. You'd only want to do this on websites aimed at technical users, because following such a link will provoke a HTTP Basic Authentication challenge that you have to cancel out of.

PS: You can apparently clear this information through 'Clear Recent History' by invoking that and then carefully selecting only 'Active Logins'. Since clearing any degree of history is an alarming thing for me and a mistake could be very bad (I keep my browser history forever), I'm not fond of this interface and don't expect to ever use it. People who are less attached to their browser history than I am (and so are more tolerant of slips than I am) may like it more.

Comments on this page:

By mappu at 2020-03-10 01:03:22:

When you submit the bad:bad@ request, the result is a 401 Unauthorized.

Another way of achieving this more seamlessly is to send a 401 Unauthorized response directly from the /logout endpoint. The browser will realize the previously-successful credentials are invalid.

Although I don't know how well this works in current browsers.

From at 2020-03-10 05:37:28:

As much as I like protocol-integrated auth, maybe mod_auth_form would suit you? It provides session-based auth with very little changes as far as Apache configuration goes.

(We use SAML2 a lot so I found Apache's mod_shib very convenient in a similar way, for slapping user auth on top of simple webapps, regular file lists, etc.)

By Joker_vD at 2020-03-10 12:10:55:

mappu, it kinda works, but the moment you want to redirect from the logout page to the login page that redirects logged in and logged out users to different places, you are in a world of pain. Some browsers re-try the credentials, some don't, some redirect, some don't, and I spent a week of trying to cobble a scheme that would consistently work for IE, Chrome, and Firefox, and gave up. The customer agreed to an IE-only working scheme, and even then, there is a spurious "Enter login/password" dialog that the user has to cancel once which seems to be impossible to get rid off.

All in all, would not recommend.

By cks at 2020-03-10 14:19:36:

My view is that the spurious authentication dialog is the real killer in exposing anything automated or even a manual link to a general population. For general use, logout needs to be smooth and silent after you hit the 'log me out' link, and you just can't do that with HTTP Basic Authentication no matter what.

By James (trs80) at 2020-03-11 11:22:25:

You can have a smooth and silent logout if you perform an AJAX request with deliberately wrong credentials, then redirect to an unauthenticated page https://tuhrig.de/basic-auth-log-out-with-javascript/

Written on 09 March 2020.
« What makes our Ubuntu updates driver program complicated
Some notes on the state of DNS over HTTPS in Firefox (as of March 2020) »

Page tools: View Source, View Normal, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Mon Mar 9 23:35:57 2020
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.