Captive Portal Test

What it detects

This test attempts to detect the presence of a captive portal using the techniques that are used by popular vendors, as well as several additional techniques devised through research on proprietary captive portal software.


If the User-defined Tests is to be run, then the user should provide an example of expected content for each URL. Otherwise, no input data is needed.


Emulated Vendor Tests

The vendors whose tests are emulated, and their corresponding captive portal detection methods are:

Google Chrome:

Google's Chromium browser/OS (commit of the implementation in chromium source), | before restoration of tabs at startup (or on a ChromeBook, before the user login panel), first attempts DNS resolution for three random hostnames of 10-byte length each (i.e. ''). Because it is quite unlikely that any, let alone all, of these hostnames actually point to a server, the test assumes they will return NXDOMAIN. In the presence of a captive portal, they will instead point to the (usually local) IP of the captive portal login page.

Microsoft NCSI:

Microsoft Network Connectivity Status Indicator (Vista and newer) will attempt to "phone home" to a Microsoft server. It firsts checks that the DNS for ! resolves to the correct IP address, and then it checks that the HTTP content of ! exactly matches "Microsoft NCSI". If anything else results from these two tests, then it is assumed that the client is behind a captive portal.

Apple iPhone/iPad/iPad:

Apple devices also phone home to a server at !, albeit they merely test for the presence of a captive portal with HTTP content matching.

Mozilla Firefox Pipeline Pre-Test:

not yet implemented

Some of the Firefox developers created a POC to test pipelining of HTTP requests, which could also potentially be used to discover captive portals, and this was rewritten in Twisted Python. Briefly the test involves the client sending a specific number of requests, which include serial numbers, at timed intervals. Each request should have a specific expected HTTP status code. The listening server begins responding after a certain amount of requests have been received, thereby providing a good indication of pipeline delay.

This idea could also be used to detect the presence of a transparent HTTP proxy.

Other Tests

The following other tests were devised based on research on captive portal software:

428 'Network Authentication Required' HTTP Status Code:

The IETF implemented another lesser-known and less-often-used HTTP status code 428, to be used by captive portal pages to notify clients and client software of the presence of the portal. It appears that thus far no captive portals have complied with the draft, so this test merely checks via HTTP fuzzy content matching on the draft itself.

DNS-0x20-to-SOA Test:

If the user specifies for this test to be additionally performed, the 0x20 "hack" will be used for a hostname, whose Start Of Authority DNS records will be requested, and a DNS resolution of the 0x20'd hostname will be sent directly to the SOA servers. The serial numbers for the SOA servers can also be checked to see if they match expected results.

Optional User-defined Tests:

If the user provides a .csv file containing list of URLs, their expected content, and expected HTTP status code, in the format:, Some Content That Should Appear, 200

then a strict HTTP content match will be performed, and failing that, fuzzy content matching.


  • If the network is behind a captive portal, and,
  • Which vendor or other test detected the presence of a captive portal.

TODO / Questions

  • Port code to Twisted
  • Implement Pipeline test?
Last modified 7 years ago Last modified on Jun 26, 2012, 4:49:00 AM