Repository navigation
Blank page on /TwoFactor/Verify after successful 2FA (double submit → bare HTTP 400) #555
Unanswered
GuidoSchaefer
asked this question in
Q&A
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Blank page on /TwoFactor/Verify after successful 2FA (double submit → bare HTTP 400)
Summary
After entering a valid TOTP code, users sometimes end up on a completely blank page at
/TwoFactor/Verify. Manually removing the path from the URL bar shows they are already logged in and the dashboard works. Cause: the verify form can be submitted twice, and the second POST fails antiforgery validation, which ASP.NET Core answers with an empty400 Bad Request.Environment
Steps to reproduce
/TwoFactor/Verify./takes 2–3 s to render on a larger archive because the dashboard computes statistics), press Enter again or click Verify a second time.What happens (reverse-proxy access log, timestamps to the second)
The second POST arrives after
HttpContext.Session.Clear()and after the new auth cookie has been issued, so the antiforgery token from the form no longer matches.[ValidateAntiForgeryToken]short-circuits with a bare 400. BecauseProgram.csconfiguresUseExceptionHandler("/Home/Error")but noUseStatusCodePages*, the browser renders an empty page while the address bar still shows/TwoFactor/Verify.Expected
Either the second submit is prevented, or a failed antiforgery check on the 2FA page sends the user to
/(already logged in → dashboard; not logged in → login page).Suggested fixes (any one is enough, both together is best)
Prevent the double submit in
Views/TwoFactor/Verify.cshtml(same idea forViews/Auth/Login.cshtml):plus
inputmode="numeric" autocomplete="one-time-code" maxlength="16"on the token input.Turn a bare 400 into a redirect for the auth pages, e.g. in
Program.cs:Alternatively an
IAntiforgery-aware filter onTwoFactorController.Verifythat redirects toHome/Indexinstead of returning 400.Workaround we use meanwhile (Nginx Proxy Manager, "Advanced" of the host)
Related
This is probably the same root cause as the unanswered discussion #443 ("HTTP ERROR 400"), where a stale antiforgery cookie on a repeated login also produces a bare 400 page. That report was attributed to the reverse proxy, but the flow above shows the proxy forwards everything correctly and the 400 originates in the app.
Side note
Safari requests
/apple-touch-icon.pngand/apple-touch-icon-precomposed.pngon every page load. Both are protected routes and answer with302 /Auth/Login?returnUrl=..., which Safari retries, producing dozens of redirects per second in the access log. Serving those two paths anonymously (or a204) would avoid that.All reactions