Skip to main content

HeaderHound

CI License: MIT

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, no default-src, wildcard sources, unsafe-inline, and unsafe-eval
  • Strict-Transport-Security — HTTPS-only evaluation, invalid/disabled values, and short max-age
  • X-Content-Type-Options and X-Frame-Options
  • Referrer-Policy and Permissions-Policy
  • Cross-Origin-Opener-Policy, Cross-Origin-Resource-Policy, and Cross-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 http and https URLs 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-private only on systems you are authorized to scan.
  • TLS certificates are verified by default. --insecure exists 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-interval is 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 policy
  • client.py: timeouts, redirect bound, TLS policy, and retrieval errors
  • analyzer.py: pure, testable header checks and score calculation
  • output.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)

Source distribution for headerhound 0.1.1
File Size Uploaded
headerhound-0.1.1.tar.gz 11.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for headerhound 0.1.1
File Interpreter ABI Platform
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 log

Release 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

Release history Release notifications | RSS feed

0.2.0

2 release files

This release

0.1.1 This release

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