Commits
Tarun Sukhani authored 799911bef37
fix(mvc): gate query-string method override behind config (PF-170, release 1.13.55)
Router.route rewrote the request method from an x-http-method-override
query-string parameter with no gate at all, while PlayHandler gated the
header form of the same feature on http.allowed.method.override. Any
state-changing route was therefore reachable by a cross-site top-level GET
navigation — precisely the shape SameSite=Lax still attaches cookies to,
since the browser decides on a GET and we convert to POST/PUT/DELETE after.
(CWE-352, reported as VULN-004 / JCLAW-1025.)
The rewrite now requires both that the target method is listed in
http.allowed.method.override (empty default) and that the wire method is
not GET. The second condition is beyond the filed fix, because the
query-string form is not purely client-supplied: FastTags._form and
FastTags._a generate it — an HTML form can only emit GET or POST, so for a
PUT/DELETE/PATCH action the tags append the parameter and submit a POST
with an authenticity token. Gating on config alone would have broken those
tags, and the config opt-in that fixes them would have reinstated the GET
elevation this closes. Refusing to elevate a GET closes the vector
regardless of config and keeps the opt-in safe.
Also trim entries on both paths, so `http.allowed.method.override=PUT,
DELETE` opts DELETE in rather than registering " DELETE" and silently
failing closed.
BREAKING: applications using #{form} or #{a} against a PUT, DELETE or
PATCH route must now list that method in http.allowed.method.override.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>