Caution
THIS CRATE IS DEPRECATED / OBSOLETE
The result of this PoC has been merged to the http-tower crate in tower-rs/tower-http#699.
I will depublish the associated crate in ~6 months (01.01.2027) from now.
This is experimental middleware for tower. It has not received a formal audit.
It provides modern CSRF protection as outlined in a blogpost by Filippo Valsorda, discussing the research background for integrating CSRF protection in Go 1.25's net/http.
This repository has been discussed in tower and the axum project respectively.
This boils down to (quoting from the blog):
- Allow all GET, HEAD, or OPTIONS requests - this implied that no relevant state changes are performed at endpoints behind such safe methods
- If the Origin header matches an allow-list of trusted origins, allow the request
- If the Sec-Fetch-Site header is present and the value is
same-originornone, allow the request, otherwise reject - If neither the Sec-Fetch-Site nor the Origin headers are present, allow the request
- If the Origin header’s host (including the port) matches the Host header, allow the request, otherwise reject it
See tests/csrf.rs for an example using Axum.
The middleware trusts whatever Origin and Host reach it. Reverse proxies and load balancers that rewrite Host (e.g. to an internal hostname) or strip Origin silently degrade the protection: the Origin/Host fallback can no longer match, and Sec-Fetch-Site becomes the only remaining line of defense. Configure intermediaries to forward both headers unchanged.