calypso
Generate csrf token, send it to frontend, put token in header in following request not working
Hello everybody
I have a react frontend and and phoenix backend. The frontend is not served from phoenix.
Now I would like to generate a csrf token in the phoenix backend, send it to the frontend and put it in the request header to access protected resources. Here are the important code snippets:
router.ex
pipeline :frontend do
plug :accepts, [“json”]
plug :fetch_session
plug :protect_from_forgery
plug :put_secure_browser_headers
endpipeline :frontend_no_csrf do
plug :accepts, [“json”]
endscope “/users/”, UserBackendWeb do
pipe_through [:frontend_no_csrf]
scope “/v1/” do
post “/csrf”, UserController, :csrf
end
end
scope “/users/”, UserBackendWeb do
pipe_through [:frontend]
scope “/v1/” do
post “/test”, UserController, :test
end
end
user_controller.ex
def csrf(conn, _opts) do
csrf_token = get_csrf_token()
conn
|> put_resp_cookie(“_csrf_token”, csrf_token, sign: false, same_site: “secure”)
|> json(%{_csrf_token: csrf_token})
end
To access now http://localhost:4000/users/v1/test I use postman and the header is correctly set:
x-csrf-token: fHcxKyYgdz9paj0ZIkkKAD4WL3EQGXU808TIEGEf-ZTwo-8KkWY7ZaLE
Content-Type: application/json
User-Agent: PostmanRuntime 7.28.0
Accept: /
Postman-Token: 4ae26e18-87d9-4d61-9bf5-d8e16f726486
Host: localhost:4000
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 73
Cookie: _csrf_token=fHcxKyYgdz9paj0ZIkkKAD4WL3EQGXU808TIEGEf-ZTwo-8KkWY7ZaLE
Put I get a 403 back, because the token seems not to be seen?
Converted error Plug.CSRFProtection.InvalidCSRFTokenError to 403 response
Where do I make a mistake?
Best
Most Liked
derek-zhou
The point of csrf is to verify two things match, usually a hidden field in the form matches with the session. The csfr token by itself does not prove anything. You’d need to maintain a phoenix session cookie as well.
calypso
So the actual solution would be to to be store the csrf_token in the session.
def csrf(conn, _opts) do
csrf_token = get_csrf_token()
conn
|> put_session(“_csrf_token”, Process.get(:plug_unmasked_csrf_token))
|> json(%{_csrf_token: csrf_token})
Consequently the token in the x-csrf-token header will be valid.
wanton7
Are you sure you even need CSRF token? If you are creating a JSON only API and verify POST content type is application/json I don’t think there is a way to do an CSRF attack if your CORS headers are properly set.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









