Handle CSRF token error gracefully
Nobody has claimed this yet.
- Dominant language
- Elixir
- Stars
- 296
- Forks
- 86
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 50
Description
Describe the bug
Submitting the login form (POST /users/log_in) with a stale CSRF token raises Plug.CSRFProtection.InvalidCSRFTokenError and the user sees the default 403 error page.
The most common trigger for real users: log in, click the browser back button, the cached login form is re-submitted with the pre-login CSRF token. Lightning's UserAuth.new_session/2 calls configure_session(renew: true) |> clear_session(), so the old token no longer matches the (new, empty) session.
You can recreate this by opening the login page on two different tabs and then login on each page without refreshing. Currently, you get this Forbidden page
Sentry
LIGHTNING-NS — 3,397 events, 94 users, ongoing since 2024-11-11.
https://openfn.sentry.io/issues/6056897474/
Bot scanners account for a large share (top 2 IPs = ~54% of recent introspectable events, heavily concentrated Chrome 131 fingerprint, scans of bare GCP IPs), but real users hit it too.
Version number
v2.16.5
Expected behavior
When CSRF validation fails on a browser request, redirect to /users/log_in with a flash like "Your session expired. Please try again." instead of rendering the 403 page.
Proposed fix
- Add
LightningWeb.Plugs.CSRFProtectionWithFallbackthat wrapsPlug.CSRFProtection.call/2intry/rescueand onInvalidCSRFTokenErrordoesput_flash |> redirect(to: ~p"/users/log_in") |> halt(). Use it in place ofplug :protect_from_forgeryin the:browserpipeline. - Add
Plug.CSRFProtection.InvalidCSRFTokenErrortoLightning.SentryEventFilter@ignored_exceptions(lib/lightning/sentry_event_filter.ex) so any remaining occurrences (non-browser pipelines) stop creating Sentry noise.
The rescue is not a security regression — the token still fails validation, the request is still rejected, the response just becomes a 302 to a GET instead of a 403 page.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the :browser pipeline and the existing plug :protect_from_forgery entry point, then read lib/lightning/sentry_event_filter.ex. Implement the proposed CSRF fallback and add the exception to @ignored_exceptions; done means stale browser submissions redirect to /users/log_in with the session-expired flash while non-browser occurrences no longer create Sentry noise.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- elixir
- Domain
- authentication, backend, security
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100