Context
HeaderProof currently detects CSRF-related cookie and method signals, but it does not inspect HTML forms. The documented DVWA low-CSRF measurement therefore has a real false negative: the state-changing password form has no anti-CSRF token, while the scanner only observes cookie hardening.
I reproduced the same boundary on current main with a controlled localhost fixture:
- a POST form with no anti-CSRF token,
- the same POST form with a hidden csrf_token,
- a benign GET search form.
HeaderProof does not distinguish the form structure in any of the three cases.
Desired behavior
Add a conservative form-level CSRF observation without turning token absence into a reportable vulnerability by itself.
A same-origin HTML response containing a plausibly state-changing form with no recognizable anti-CSRF token may produce an observed candidate such as csrf_form_without_token. A token-bearing equivalent and ordinary GET search/navigation forms should not produce that candidate.
This is an observation boundary, not proof of exploitable CSRF. Applications may enforce Origin/Referer, SameSite, custom request requirements, or server-side state that is not visible from the form.
Design constraints
- Keep the detector passive at this stage; do not submit forms or mutate application state.
- Parse only the bounded response body already retained by HeaderProof.
- Do not promote the observation to a finding solely because a token is absent.
- Record enough evidence to explain why the form was classified as plausibly state-changing without persisting form secrets or arbitrary field values.
- Avoid treating search, filter, pagination, login, and other clearly non-state-changing forms as CSRF findings/candidates merely because a token is absent.
- Preserve the existing evidence-gate model: exploitability requires independent state-change / cross-site enforcement proof.
Acceptance criteria
- Controlled tokenless state-changing form is represented by an explicit CSRF form observation.
- Equivalent form with a recognizable anti-CSRF token is suppressed.
- Benign GET search form is suppressed.
- Existing cookie/method observations remain unchanged.
- DVWA measurement can credit the explicit form observation without pretending exploitability was proven.
- False-positive-oriented fixtures cover token-bearing and clearly non-state-changing forms.
- Full Ruff, mypy and pytest gates remain green.
Please propose the form classification/token-recognition boundary before implementation; precision matters more than detector count here.
Context
HeaderProof currently detects CSRF-related cookie and method signals, but it does not inspect HTML forms. The documented DVWA low-CSRF measurement therefore has a real false negative: the state-changing password form has no anti-CSRF token, while the scanner only observes cookie hardening.
I reproduced the same boundary on current main with a controlled localhost fixture:
HeaderProof does not distinguish the form structure in any of the three cases.
Desired behavior
Add a conservative form-level CSRF observation without turning token absence into a reportable vulnerability by itself.
A same-origin HTML response containing a plausibly state-changing form with no recognizable anti-CSRF token may produce an observed candidate such as csrf_form_without_token. A token-bearing equivalent and ordinary GET search/navigation forms should not produce that candidate.
This is an observation boundary, not proof of exploitable CSRF. Applications may enforce Origin/Referer, SameSite, custom request requirements, or server-side state that is not visible from the form.
Design constraints
Acceptance criteria
Please propose the form classification/token-recognition boundary before implementation; precision matters more than detector count here.