Skip to main content

Captive Portal Detector

A Python utility to perform high-security network-integrity checks.
It reliably detects captive portals and can identify TLS Man-in-the-Middle (MITM) attacks using SPKI pinning against redundant, user-controlled endpoints.

Features

  • High-Security MITM Detection: Uses SPKI-pinning against redundant, user-controlled endpoints to detect sophisticated TLS interception.
  • Comprehensive Checks: Runs a suite of probes in parallel, including standard HTTP 204 checks, random domain requests, and IPv6 reachability tests.
  • Resilient by Design: The final verdict prioritizes security, trusting only a successful pinned connection to declare the internet "OK".
  • Fast and Lightweight: Concurrent probes provide a result in seconds with minimal overhead.

Usage

Install via pip:

pip install captive-portal-detector

CLI Usage

Simply run it with: capdet

Advanced CLI Usage (detailed probe suite)

sudo capdet [--advanced | -a] [--json]

Python Usage

from capdet.network_probe import NetworkProbe

status = NetworkProbe().network_health()
print(status)

or

from capdet.advanced_network_analyzer import AdvancedNetworkAnalyzer
ana = AdvancedNetworkAnalyzer()

result = ana.analyze_network_interference()
print(result)

Advanced Usage (with your own pinned servers)

The library's real power is using your own endpoints. You can override the PINNED dictionary by passing it to the constructor:

from capdet.network_probe import NetworkProbe
custom_pinned = {
    "c1": "sha256/your_custom_spki_hash1",
    "c2": "sha256/your_custom_spki_hash2"
}
network_probe = NetworkProbe(pinned=custom_pinned)
status = network_probe.network_health()
print(status)

Output

The network_health() method returns one of three clear verdicts:

OK: A trusted, pinned TLS connection was successful. Internet access is confirmed.
CAPTIVE: A definitive captive portal (redirect) or TLS pin mismatch (MITM attack) was detected.
NO_INTERNET: No definitive CAPTIVE state was found, but a trusted connection could not be established.

How It Works

The library runs multiple probes in parallel and makes a verdict based on a security-first principle:

  1. If any probe detects a captive portal (like an HTTP redirect or a TLS pin mismatch), the final verdict is immediately CAPTIVE.
  2. If no CAPTIVE state is found, it then checks if any of the high-security pinned probes returned OK. An "OK" from a simple public probe is not sufficient.
  3. If neither of the above conditions is met, the verdict is NO_INTERNET, as a trusted connection could not be established.

Security Model

This tool is designed for "zero trust" environments. Unlike simple checks, it does not trust a successful connection to a public website as proof of real internet access. The default PINNED servers (c1/c2.probecheck.fyi) provide a baseline but it's recommended you add your own for maximum security. This allows the tool to reliably detect most corporate and nation-state MITM interception attacks.

Metadata

Release files for captive-portal-detector 1.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for captive-portal-detector 1.1.2
File Size Uploaded
captive_portal_detector-1.1.2.tar.gz 14.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for captive-portal-detector 1.1.2
File Interpreter ABI Platform
captive_portal_detector-1.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 28.6 kB

Release files / captive_portal_detector-1.1.2.tar.gz

Download URL captive_portal_detector-1.1.2.tar.gz
Size 14.1 kB
Tags Source
SHA-256 checksum
How to use checksums
1aca947f8277bd88e83c247a0cfcd9c67f45b49c5c9483db4f2f277af9ed1891
BLAKE2b-256 checksum
How to use checksums
b4d6ea4085ffb578c31a6ab8ec10a2589efddfcf288b50e4377209f49555d58f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.11.5

Release files / captive_portal_detector-1.1.2-py3-none-any.whl

Download URL captive_portal_detector-1.1.2-py3-none-any.whl
Size 14.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b844e1789356329a0670bbe7881f15f183908f7e47db055a5eef0e5c9213255b
BLAKE2b-256 checksum
How to use checksums
0416affa65ad6d21b248fbc5334238350e60561b9a758125324e746d2f16e16e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.11.5

Release history Release notifications | RSS feed

This release

1.1.2 This release

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page