How does Firefox know my ISP login page?

So, my question is how can Firefox know that login page address?

It doesn't, actually.

Your ISP uses a technology known as a Captive Portal. Captive portals work by "somehow" hijacking the browser's HTTP request and re-directing it to the login portal.

This "somehow" can be achieved in different ways, for example

  • HTTP Redirect
  • ICMP Redirect
  • DNS Hijacking

Your browser, in turn, tries to detect this "hijacking" by trying to retrieve a well-known web page and checking whether the response they get back is the response they are expecting or something else. Here are some examples of pages that such "hijacking detection systems" use:

  • http://captive.apple.com/ (Apple)
  • http://msftconnecttest.com/ (Microsoft)
  • http://connectivitycheck.gstatic.com/generate_204 (Google)
  • http://clients3.google.com/generate_204 (Android pre-6.0)
  • http://detectportal.firefox.com/success.txt (Firefox)

The Google one gives a hint as to how it works: The webserver will respond with an HTTP 204 No Content status code. A captive portal, however, will return content (otherwise it would be useless) and therefore never answer with a 204 status code. Most likely, it will use a 307 Temporary Redirect to tell the browser to fetch a different URI (the URI of the captive portal login page).

The other ones use a small document with well-known content instead (e.g. Apple's simply contains the word "Success").

The hijacking detection doesn't have to be performed by the browser, actually. Most modern devices will automatically run this "captive portal hijacking detection" automatically whenever they connect to an open WiFi and automatically pop up a dialog allowing you to go to the captive portal, without you having to explicitly open up your browser and visit some web page.

The reason for this is that in the modern Internet world, a browser is not necessarily the first app a user would be trying to use the Internet with. It could be the Facebook client, WhatsApp, or email client, for example.

Note that I used the term "hijacking" deliberately. These techniques are actually basically performing a Man-in-the-Middle attack. (The difference being that a "real" attacker would try to redirect you to a website that looks exactly like the one you wanted to visit and trick you into entering your username and password on the fake website.) Hence, these techniques only work as long as you are trying to visit an "insecure" website, i.e. a website that does not use SSL/TLS (i.e. no https://), does not use HTTP Strict Transport Security (HSTS), and the likes.

This is starting to become a problem, because more and more websites are only accessible through HTTPS (TLS). Modern browsers remember whether a website supports HTTPS and will use the HTTPS version, regardless of what you enter in the URI bar. Techniques such as HSTS ensure that browsers will always use the encrypted version of a website. Newer versions of the HTTP protocol such as HTTP/2 and HTTP/3 don't strictly require encryption, but all major browser vendors have decided to only implement them for HTTPS connections.

If you try to visit Facebook or SuperUser, for example, your browser will automatically use an encrypted, authenticated connection, and when the captive portal tries to redirect the browser to the login page, the browser will detect this manipulation and throw an error. Normally, this is exactly what you want, but in this case, it will prevent you from logging into the captive portal and thus from using the Internet.

If you ever run into problems where you are connected to the WiFi, but your apps show errors or load indefinitely, the reason is almost certainly that for some reason you are not logged into the captive portal. Maybe you didn't see the notification popup, maybe the detection failed, there can be many reasons.

In this case, you can solve the problem by visiting a website that you know is "insecure", i.e. doesn't use HSTS, SSL/TLS, or HTTP/2 (the standard specifies both HTTP and HTTPS, but browser vendors have decided that they will support only HTTPS for HTTP/2 going forward). The above-mentioned URIs should do the trick, but there is actually a website which some nice people have put up that serves exactly this purpose, and whose URI is easy to memorize: http://neverssl.com/.

NeverSSL does exactly what its name suggests: it is simply a completely useless website whose sole purpose is to never use SSL/TLS, HSTS, HTTP/2, QUIC or anything other than un-encrypted, un-authenticated, insecure, plain HTTP/1.1, so that the captive portal can intercept the request and redirect to its login page.


The feature is called Captive Portal Detection. Firefox will try to fetch http://detectportal.firefox.com/success.txt and if record the answer. If there's a redirect, it knows that there is a login page and will pop up the warning.

A quick writeup that explains the feature and shows how to disable it if needed is at http://support.moonpoint.com/network/web/browser/firefox/detect_portal/


Besides the very complete @JörgWMittag answer, captive portals also implement the WISPr protocol, defined by the Wifi Alliance, which should be understood by any client/router/AP implementing captive portals.

It is present in the captive portals implementation of major vendors, namely Cisco and Aruba, and also in the captive portal implementation in PfSense.

Firefox does too understand it, and WISPr in itself triggers the famous automatic Apple authentication restricted browser (CNA). (afair from my tests, redirects alone are not enough to trigger those windows, at least in Apple equipments)

The actual WISPr is present in the main page the client is redirected to as HTML tags, and defines URLs for the login, logout, and abort pages. It also defines status codes for the pages generated by those URLs.

As in:

<!-- WISPr message -->^M
<span class="displayNone"><!--<?xml version="1.0" encoding="UTF-8"?>^M
<WISPAccessGatewayParam xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.acmewisp.com/WISPAccessGatewayParam.xsd">^M
<Redirect>^M
<AccessProcedure>1.0</AccessProcedure>^M
<LoginURL>https://xxxx/captive/noswifi?hmac=xxxx&amp;res=notyet&amp;uamip=xxxx&amp;uamport=80&amp;userurl=&amp;challenge=xxxxxxe&amp;nasid=BC-14-01-XX-XX-XX&amp;mac=00-15-AF-XX-XX-XX</LoginURL>^M
<AbortLoginURL>http://xxxx:80/captive/logoff</AbortLoginURL>^M
<MessageType>100</MessageType>^M
<ResponseCode>0</ResponseCode>^M
<AccessLocation>FonZON:PT</AccessLocation>^M
</Redirect>^M
</WISPAccessGatewayParam>-->^M
</span>

For more details (and clues) about how to implement/deal with captive pages, see my other answers:

Getting WISPr tags from a FON authentication portal

Implementing a Captive portal using Apache

Captive portal detection, popup implementation?

Related:

Disabling CNA in MacOS

How use a captive portal when in text mode?

PS Interestingly enough, some CPEs/cable modems are (ab)using WISPr to show to customers, in their browsers, error messages in the absence of an Internet connection/when booting.

Tags:

Firefox