A modern approach to preventing CSRF in Go (via) Alex Edwards writes about the new http.CrossOriginProtection
middleware that was added to the Go standard library in version 1.25 in August and asks:
Have we finally reached the point where CSRF attacks can be prevented without relying on a token-based check (like double-submit cookies)?
It looks like the answer might be yes, which is extremely exciting. I've been tracking CSRF since I first learned about it 20 years ago in May 2005 and a cleaner solution than those janky hidden form fields would be very welcome.
The code for the new Go middleware lives in src/net/http/csrf.go. It works using the Sec-Fetch-Site HTTP header, which Can I Use shows as having 94.18% global availability - the holdouts are mainly IE11, iOS versions prior to iOS 17 (which came out in 2023 but can be installed on any phone released since 2017) and some other ancient browser versions.
If Sec-Fetch-Site
is same-origin
or none
then the page submitting the form was either on the same origin or was navigated to directly by the user - in both cases safe from CSRF. If it's cross-site
or same-site
(tools.simonwillison.net
and til.simonwillison.net
are considered same-site
but not same-origin
) the submission is denied.
If that header isn't available the middleware falls back on comparing other headers: Origin
- a value like https://simonwillison.net
- with Host
, a value like simonwillison.net
. This should cover the tiny fraction of browsers that don't have the new header, though it's not clear to me if there are any weird edge-cases beyond that.
Note that this fallback comparison can't take the scheme into account since Host
doesn't list that, so administrators are encouraged to use HSTS to protect against HTTP to HTTPS cross-origin requests.
On Lobste.rs I questioned if this would work for localhost
, since that normally isn't served using HTTPS. Firefox security engineer Frederik Braun reassured me that *.localhost
is treated as a Secure Context, so gets the Sec-Fetch-Site
header despite not being served via HTTPS.
Recent articles
- NVIDIA DGX Spark: great hardware, early days for the ecosystem - 14th October 2025
- Claude can write complete Datasette plugins now - 8th October 2025
- Vibe engineering - 7th October 2025