HeaderHound
HeaderHound is a defensive, explainable command-line scanner for HTTP response security headers. It requests one URL, follows a bounded redirect chain, and reports missing or risky configurations in a readable terminal table or stable JSON.
It is intended for systems you own or are authorized to assess. It does not crawl, exploit vulnerabilities, fuzz endpoints, or perform destructive actions.
Install
HeaderHound requires Python 3.10 or newer. Once a release is published to PyPI, install it with either pip or pipx:
python -m pip install --upgrade headerhound
# or, for an isolated command-line application:
pipx install headerhound
For an unreleased source checkout, use python -m pip install . instead.
Packaging and distribution
GitHub releases are the source of versioned distributions. The release workflow builds a wheel and source distribution, validates both, and publishes them to PyPI with PyPI Trusted Publishing. It uses GitHub Actions OIDC and does not store a PyPI API token in this repository.
After publication, install the latest release with:
python -m pip install --upgrade headerhound
pipx install headerhound
The published project page lists the exact wheel and source-distribution files for every release.
Usage
headerhound https://example.com
headerhound https://example.com --format json
headerhound https://example.com --format json --fail-under 80
headerhound https://service.internal --allow-private --timeout 15
Example terminal output:
Target: https://example.com/
Final URL: https://example.com/
HTTP status: 200
Security score: 78/100 (grade C)
+----------+-----------------------------------+--------------------------------+
| Severity | Finding | Details |
+----------+-----------------------------------+--------------------------------+
| HIGH | Content-Security-Policy missing | The browser receives no policy |
+----------+-----------------------------------+--------------------------------+
Exit status is 0 for a completed scan and 2 for invalid input or retrieval failure. JSON errors are written to standard error as {"error": "..."}.
Use --fail-under SCORE to return exit status 1 when a completed scan is below a chosen CI threshold.
Checks
HeaderHound assesses the presence and selected high-signal weak configurations of:
Content-Security-Policy— including report-only mode, nodefault-src, wildcard sources,unsafe-inline, andunsafe-evalStrict-Transport-Security— HTTPS-only evaluation, invalid/disabled values, and shortmax-ageX-Content-Type-OptionsandX-Frame-OptionsReferrer-PolicyandPermissions-PolicyCross-Origin-Opener-Policy,Cross-Origin-Resource-Policy, andCross-Origin-Embedder-Policy
The score begins at 100 and subtracts documented weighted findings. It is a prioritization aid, not a compliance result or a substitute for application-specific review.
Safety and network behavior
- Only
httpandhttpsURLs are accepted; credentials embedded in URLs are rejected. - By default, targets resolving to loopback, private, link-local, multicast, reserved, or unspecified addresses are rejected. Use
--allow-privateonly on systems you are authorized to scan. - TLS certificates are verified by default.
--insecureexists only for authorized diagnostic use. - The default timeout is 10 seconds, redirects are limited to 5, and the client disables environment proxy settings.
- One request is made per invocation.
--min-intervalis available for integrations which reuse the client.
Private-address filtering is a useful guardrail, not a complete SSRF defense against DNS rebinding or hostile networks. Run scans from a suitably restricted network when targets may be untrusted.
Architecture
CLI → URL validation / target policy → bounded HTTP client → header analyzer → table or JSON renderer
safety.py: URL validation and conservative public-target policyclient.py: timeouts, redirect bound, TLS policy, and retrieval errorsanalyzer.py: pure, testable header checks and score calculationoutput.py: dependency-free terminal and JSON reports
Limitations
HeaderHound evaluates only the final HTTP response (while reporting the redirect chain). It cannot determine whether a header is consistently set on every route, whether a CSP is compatible with the application, whether TLS configuration is strong, or whether application behavior is secure. Security headers are defense in depth.
Development
python -m pip install -e '.[dev]'
ruff check .
ruff format --check .
pytest
See CONTRIBUTING.md, SECURITY.md, and ROADMAP.md.
License
MIT. See LICENSE.
Metadata
Release files for headerhound 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| headerhound-0.1.1.tar.gz | 11.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| headerhound-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 25.3 kB
Release files / headerhound-0.1.1.tar.gz
| Download URL | headerhound-0.1.1.tar.gz |
|---|---|
| Size | 11.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ac0d051275005bad5cabcfa00be884838ed5a6c6ae3fbaba42f7500a1db1ce99
|
|
BLAKE2b-256 checksum How to use checksums |
aa5c57c1cac20eb22d77dafc9d9ff4c1e0c5e8fb1235779f07981f58973f5562
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 7, 2026.
Transparency logRelease files / headerhound-0.1.1-py3-none-any.whl
| Download URL | headerhound-0.1.1-py3-none-any.whl |
|---|---|
| Size | 13.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f9e791c4acd68637ad038c4599444d1a5161757dcd034d474831404900899990
|
|
BLAKE2b-256 checksum How to use checksums |
cbf5c95b2f5d0c7d102bf956865f36b0f86113d673c3752de321e43a3606934f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 7, 2026.
Transparency log