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:
- If any probe detects a captive portal (like an HTTP redirect or a TLS pin mismatch), the final verdict is immediately CAPTIVE.
- 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.
- 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)
| File | Size | Uploaded | |
|---|---|---|---|
| captive_portal_detector-1.1.2.tar.gz | 14.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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
|