Passive external attack-surface scanner — find your exposed subdomains, expiring certs, missing security headers, and dangling DNS before attackers do.
Project description
perimeter-scan
Passive external attack-surface scanner. Find your exposed subdomains, expiring certs, missing security headers, and dangling DNS that could be hijacked — before an attacker (or a prospect's security team) does.
One command, no agent, no signup:
$ perimeter-scan example.com
It's passive: it reads public Certificate Transparency logs and DNS, and makes standard web requests to the hosts it finds. No exploitation, no port scanning, no authenticated probing. Only scan domains you own or are authorized to assess.
What it checks
| Check | How |
|---|---|
| Subdomains | enumerated from public Certificate Transparency logs (crt.sh) |
| TLS hygiene | expired, expiring-soon, and self-signed certificates |
| Security headers | missing HSTS / CSP / anti-clickjacking / MIME-sniffing headers |
| Subdomain takeover | dangling CNAMEs pointing at unclaimed third-party services |
Install
$ pipx install perimeter-scan # recommended (isolated)
# or
$ pip install perimeter-scan
Requires Python 3.11+.
Usage
$ perimeter-scan example.com # human-readable report
$ perimeter-scan example.com --json # machine-readable JSON
$ perimeter-scan example.com --min-severity high # only high+ findings
$ perimeter-scan example.com --max-subdomains 100 # scan more hosts
$ perimeter-scan example.com --fail-on high # exit 1 if any high+ finding (for CI)
In CI — fail the build on a new exposure
# .github/workflows/attack-surface.yml
- run: pipx install perimeter-scan
- run: perimeter-scan yourcompany.com --fail-on high --json
As a library
import asyncio
from perimeter_scan import passive_scan, ScanConfig
result = asyncio.run(passive_scan("example.com", config=ScanConfig(max_subdomains=50)))
print(result.risk_score, result.counts_by_severity())
for f in result.findings:
print(f.severity.value, f.asset, f.title)
A one-time scan is a snapshot. Your attack surface changes every deploy.
perimeter-scan is the open-source scanner behind Perimeter.
The CLI tells you what's exposed right now. Perimeter runs it continuously, remembers
what it saw last time, and alerts you the moment something new appears — a fresh
subdomain, a cert about to lapse, a dangling record someone could hijack — so you find
it before anyone else does.
→ Monitor your domain continuously
License
MIT. Contributions welcome.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file perimeter_scan-0.1.0.tar.gz.
File metadata
- Download URL: perimeter_scan-0.1.0.tar.gz
- Upload date:
- Size: 17.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
faa68e964396f54c5b76bb39f113e8d8f8722672cc8422fe2bd17ab148a83a84
|
|
| MD5 |
7f9ed26c088fe8e433dbe9ec07adf182
|
|
| BLAKE2b-256 |
656454105e926a531de02d81726d9790cf7b6fb87f99135fa31e8a38b053e489
|
File details
Details for the file perimeter_scan-0.1.0-py3-none-any.whl.
File metadata
- Download URL: perimeter_scan-0.1.0-py3-none-any.whl
- Upload date:
- Size: 18.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
06cf1f9ecff15a80d88efcf2f1e5a4f7bddc731299209ce1299a17b3ef8534ce
|
|
| MD5 |
86a6d3014a7f3ed0f5deba005cc7d77e
|
|
| BLAKE2b-256 |
1f63caa5c3f490ced9c15054769211d6f339b0a14f66e8b4c7748e18208131b5
|