engineeringdept
In 2026 double submit/session tokens are no longer necessary to prevent against CSRF attacks. Instead, we can use the Sec-Fetch-Site header, with a fallback of the Origin header. This has a couple of advantages:
- Removes a whole class of easy-to-make mistakes around CSRF token handling - e.g. accidentally not passing a token through to a JS request
- Removes any issues related to long-lived CSRF tokens in non-cookie session storage - e.g. a user returning to the site after their CSRF token has disappeared from the Redis backed session storage and their next actions failing
This blog post does a good job of outlining how to prevent against CSRF attacks using these headers and the issues around legacy browsers. It has been adopted in Go 1.25 in the net/http middleware.
I’ve had a go at implementing a Plug which does same: GitHub - breakroom/plug_cross_origin_protection: A Plug to protect against Cross-Site Request Forgery (CSRF) attacks using modern header-based checks instead of tokens · GitHub (this is not yet in production, but likely will be after more thorough review.)
Is there any interest in adopting this approach in Plug/Phoenix and dropping CSRF tokens ( Plug.CSRFProtection — Plug v1.20.2 ) entirely? Or should I continue with a separate library?
Trending in Proposals: Ideas
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixirconf-us
- #ai
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 5- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
josevalim
Ship your thing and collect feedback! That will be useful for upstreaming it later when the time is right!
LostKobrakai
I was looking at the readme. I don‘t think the skip example is correct. The plug in the controller would only run after the plug in e.g. the router pipeline. So you‘d store the intent to skip after the skippable plug already executed.
I‘m also curious about the exception. Imo an exception should be the default with a
Plug.Exceptionintegration to turn it into a 403 (e.g. have a plug_status field of 403). That‘s how plug itself handles that.I also see you using the
Plugnamespace. Before publishing you‘d want to change that to your own namespace: Library Guidelines — Elixir v1.12.3derek-zhou
I use
Originheader alone in production. Besides what you mentioned, there is at least one more problem with CSRF tokens nowadays because:By not generating and storing CSRF tokens, I avoided thrashing my session storage.
engineeringdept
Ah yes, thanks! I’ve removed that namespace, made exception the default, and removed the
skipfunctionality, which as you highlight only works if you’re controlling the plug invocation downstream.engineeringdept
Yes, this is another issue that also affects us.