Evidence-first active web security scanning.
Reproduce the technical primitive before promoting a signal to a finding.
Why HeaderProof · Quick start · Checks · Evidence · Configuration · Docs · Contributing
HeaderProof is an evidence-gated active scanner for header-driven web security issues. It targets CORS, CSRF, header injection / response splitting, cache poisoning, and content spoofing while treating false positives as a primary failure mode.
Most scanners are good at producing signals. HeaderProof is built around the harder question: what technical evidence is strong enough to promote a signal into a finding?
A detector can observe suspicious behavior without reporting it as a vulnerability. HeaderProof records the probe and observation, applies a detector-specific evidence gate, filters weak or incomplete proof, and only then emits a finding.
Important
HeaderProof proves technical behavior, not real-world victim impact. Every reported result still requires appropriate manual validation before disclosure.
| Principle | What it means |
|---|---|
| Evidence before alerts | A console finding is never emitted before its detector-specific technical gate passes. |
| Lower false-positive noise | Weak or incomplete signals remain auditable observations instead of becoming findings. |
| Reproducible proof states | Evidence progresses through explicit states such as observed, reproduced, and cross_request_confirmed. |
| Cross-request verification | Cache poisoning uses separated clean, poison, victim, and control request roles. |
| Auditable runs | Findings, observations, probes, coverage, and operational errors are persisted independently. |
| Automation ready | Stable exit codes plus JSONL, JSON, Markdown, and SARIF exports fit CI and recon pipelines. |
| Extensible | Declarative HTTP templates can add bounded same-target detectors without new Python detector code. |
| Minimal runtime | The Python package has no third-party runtime dependencies. |
curl -fsSL https://raw.githubusercontent.com/TayfurYldz/headerproof/main/install.sh | shVerify the installation:
headerproof --versionYou can also run the published container:
docker run --rm ghcr.io/tayfuryldz/headerproof:latest --versionheaderproof example.comsubfinder -silent | httpx -silent | headerproof -silentheaderproof example.com -severity high,medium -o findings.jsonlHeaderProof accepts a single target, target lists, and stdin streams, making it suitable for both focused verification and larger authorized workflows.
HeaderProof currently focuses on five security areas:
| Check | Verification focus |
|---|---|
| CORS | Arbitrary and null origins, origin reflection, credential combinations, preflight behavior, and cache-relevant CORS signals. |
| CSRF | Authentication-cookie and unsafe-method indicators while deliberately avoiding claims that cookie hardening alone proves CSRF. |
| Header injection | Forwarding-header influence, response-header reflection, CRLF / response-splitting candidates, and optional OOB-capable probes. |
| Cache poisoning | Persistence across isolated poison/victim/control requests, cache-key separation, and cache-hit evidence. |
| Content spoofing | Controlled canary reflection in security-relevant response content and headers. |
The scanner intentionally favors bounded probes and evidence quality over broad, destructive request behavior.
┌───────────────┐
Target ──► Baseline ──► Probes ──► Detector candidate
│
▼
Evidence gate
╱ ╲
╱ ╲
gate passes weak / failed
│ │
▼ ▼
False-positive Observation
filter retained
│
▼
Finding
observed— a relevant response property was seen.reproduced— detector-specific replay reproduced the technical primitive.cross_request_confirmed— independent request roles confirmed the primitive.
Technical reproduction and impact are intentionally separate. HeaderProof does not automatically convert a reproduced primitive into a claim about exploitable victim impact.
Cache poisoning receives a stricter multi-request workflow. HeaderProof separates the request roles and verifies that the candidate behavior survives into the expected victim request while remaining absent from a fresh control path. Cache-hit semantics are interpreted independently for supported cache/CDN evidence.
This design is intended to distinguish a reflected request header from actual shared-cache persistence.
The default output is intentionally compact and grep-friendly:
[response_splitting_crlf_candidate] [high] [reproduced] https://example.com/path
Use:
-jsonfor JSONL output.-sariffor SARIF.-vfor compact proof notes.-oto write findings to a file.
Findings use stdout; operational messages use stderr, so pipelines can consume results without mixing them with scanner status messages.
Evidence is stored under:
${XDG_STATE_HOME:-~/.local/state}/headerproof/runs/
└── <run>/
├── results.jsonl
├── signals.jsonl
├── observations.jsonl
├── probes.jsonl
├── coverage.jsonl
└── errors.jsonl
The separation matters: a probe can be attempted, produce an observation, fail a proof gate, and remain available for later review without polluting the verified finding stream.
| Code | Meaning |
|---|---|
0 |
No verified finding |
1 |
One or more verified findings |
2 |
Scan error |
130 |
Interrupted |
Repeated probe inputs and request context can be stored in headerproof.yaml:
origins:
- https://origin.example
headers:
- X-Custom-Cache-Key
request_headers:
X-Test-Context: authorized-lab
rate_limit: 5
timeout: 2.5
severity: high,mediumSupported configuration includes origins, custom probe headers, runtime request headers, concurrency, rate limiting, timeouts, severity filtering, and OOB settings. CLI values override matching configuration values.
Request-header values are used at runtime but are not copied into run metadata. See Configuration for the full behavior.
HeaderProof separates the scanner engine from its distributable detector definitions.
Existing bounded primitives cover specialized workflows such as baseline, preflight, origin probes, query/header probes, cache state machines, CRLF probes, and OOB header probes. For simpler same-target checks, declarative HTTP templates can use safe GET, HEAD, or OPTIONS requests with matchers, extractors, finding metadata, and an independent evidence gate.
Template variables include:
{{canary}} {{hostname}} {{url}}
Update the validated detector set with:
headerproof -update-templatesDetector updates are distributed separately through the headerproof-templates repository.
Input
│
▼
Orchestration ──► Transport ──► Detection
│
▼
Evidence gating
│
┌─────────────┴─────────────┐
▼ ▼
Findings Observations
│ │
└──────────► Output ◄───────┘
The core modules deliberately keep responsibilities separate:
| Component | Responsibility |
|---|---|
cli.py |
Stable CLI surface and process exit contract |
input.py |
Target, file, and stdin normalization |
engine.py |
Bounded detector scheduling per URL |
transport.py |
HTTP exchanges and request pacing |
detectors.py |
Probe context and candidate signal generation |
templates.py |
Declarative request/matcher/extractor/gate validation |
evidence.py |
Technical evidence gating |
output.py |
Append-only evidence persistence and exports |
See Architecture for the project-level design.
HeaderProof's test strategy treats false positives as a first-class failure mode.
The repository includes:
- Unit and integration tests.
- Ruff and mypy quality gates.
- Branch coverage gates for detector/evidence code.
- Real Varnish and nginx cache fixtures.
- Optional provider-backed Cloudflare and Fastly fixtures.
- A known-vulnerable DVWA measurement that explicitly documents a current CSRF false-negative boundary.
- Package build/install smoke tests in CI.
Controlled fixture measurements are published with their limitations rather than presented as internet-wide accuracy claims. See Testing and Project Proof.
HeaderProof is designed to fit into existing security workflows:
- GitHub Actions: headerproof-action preserves the scanner's exit semantics and supports SARIF export.
- Detector updates: headerproof-templates distributes validated detector definitions independently of the scanner binary.
- Containers: release automation publishes a GHCR image.
- Release artifacts: platform binaries, Python distributions, checksums, signatures, and provenance/attestation material are produced by the release workflow.
HeaderProof is not intended to replace a general-purpose vulnerability scanner or content fuzzer. It focuses on header/cache security primitives where reproducible evidence and request relationships matter.
| Tool | Primary role |
|---|---|
| HeaderProof | Evidence-gated verification of header/cache security behavior |
| Nuclei | Broad template-driven vulnerability scanning |
| Corsy | Focused CORS testing |
| ffuf | Web fuzzing and content discovery |
These tools can complement each other in an authorized testing workflow.
Start with the Documentation index for the maintained source of truth across user, contributor, and maintainer documentation.
| Resource | Description |
|---|---|
| Architecture | Components, data flow, and architectural invariants |
| Configuration | YAML configuration and precedence |
| Testing | Evidence states, fixtures, metrics, and known limitations |
| Project Proof | Evidence/publication rules and project proof |
| Discovery | Discovery workflow documentation |
| PyPI | Package publishing/install information |
| CI | Continuous-integration details |
| Roadmap | Current project direction |
| Changelog | Release history |
| Security | Vulnerability reporting and authorized-testing policy |
A controlled terminal walkthrough is available in docs/headerproof-demo.cast.
Contributions that reduce false positives, improve evidence quality, strengthen detector behavior, improve tests, or make verified output easier to consume are welcome.
Before opening a pull request:
- Read CONTRIBUTING.md.
- Prefer an existing
good first issueorhelp wantedissue, or discuss larger detector behavior first. - Keep changes focused and include tests for behavioral changes.
- Keep controlled fixtures, known-vulnerable labs, and real-world findings clearly separated.
- Never describe technical reproduction as victim impact without independent validation.
Local quality checks:
python3 -m compileall -q header_active_scan.py src/headerproof
python3 -m ruff check header_active_scan.py src/headerproof tests
python3 -m mypy
python3 -m pytest -q
python3 -m pytest -q --cov=headerproof.detectors --cov=headerproof.evidence --cov-branch --cov-fail-under=95See open issues and Discussions to get involved.
HeaderProof performs active HTTP probes. Use it only on systems you own or are explicitly authorized to test.
Vulnerabilities in HeaderProof itself should be reported according to SECURITY.md. Third-party vulnerabilities should not be disclosed in HeaderProof issues, pull requests, or Discussions.
HeaderProof is released under the MIT License.
HeaderProof
Evidence first. Findings second.
