traefik-forward-auth
traefik-forward-auth copied to clipboard
Always try to clear CSRF cookie
This should be done immediately after extracting the cookie
Just experienced a mystifying issue with the CSRF cookie complaining. Incognito window worked fine, but I couldn't get my browser state to login for ~ 10 minutes. I tried clearing cookies on the only domain I could get to (sso.mydomian.com - points at the forwardauth container), but it seemed like the cookie was cached at (myapp.mydomain.com), since each new request there had a csrf cookie attached.
- Navigate to
myapp.mydomain.com
, in network devtools, this request had:Cookie: _forward_auth_csrf=xxxx
- Redirect to IDP and login
- Redirect back to
sso.mydomain.com
, getNot Authorized
in the browser - Error message in forward auth container:
time="2020-12-30T07:18:32Z" level=warning msg="Error validating csrf cookie" csrf_cookie="_forward_auth_csrf=xxx" error="CSRF cookie does not match state" handler=AuthCallback host=sso.mydomain.com method=GET proto=https rule=default source_ip=1.2.3.4 uri="/__oauth__?code=xxx&state=yyy%3Aoidc%3Ahttps%3A%2F%2Fmyapp.mydomain.com%2F"
Then suddenly it started working again. Not sure what triggered the change 🤷♂️ But wanted to report since it seemed somewhat related to a "bad" CSRF cookie
EDIT: Actually, I think I know what this may have been. My staging domain is a subdomain of my primary domain (staging.sso.mydomain.com
). The forward auth csrf cookie was not being set to a different name on staging / production, and that + domain collision at sso.mydomain.com
may have been part of the contributing factor here... (I had the same problem with the primary cookie at one point, and did not think to rename the csrf cookie until now).
EDIT2: I actually think this may have been entirely my fault. I am pretty sure I briefly had a bad DNS record that was sending prod traffic to staging 😑 I suspect when that record got cleaned up and propagated, things resolved. Probably worth disregarding 😄
I am getting a similar error, works in a new session but fails when already logged in:
time="2020-12-30T21:13:47Z" level=warning msg="Error validating csrf cookie" csrf_cookie="_forward_auth_csrf=<redacted>" error="CSRF cookie does not match state" handler=AuthCallback host=auth.sub.domain.com method=GET proto=https rule=default source_ip=<my public ip> uri="/_oauth?state=<redacted>%2F&code=<redacted>&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+openid&authuser=0&prompt=none"
tfa:
image: thomseddon/traefik-forward-auth:2-arm
environment:
- PROVIDERS_GOOGLE_CLIENT_ID=${GOOGLE_CLIENT_ID}
- PROVIDERS_GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET}
- SECRET=${AUTH_JWT_SECRET}
- COOKIE_DOMAIN=${BS_URL} #sub domain
- AUTH_HOST=auth.${BS_URL}
- LOG_LEVEL=${LOG_LEVEL}
- WHITELIST=${WHITELIST}
labels:
- "traefik.enable=true"
- "traefik.http.routers.tfa.rule=Host(`auth.${BS_URL}`)"
- "traefik.http.routers.tfa.entrypoints=websecure"
- "traefik.http.routers.tfa.service=tfa"
- "traefik.http.routers.tfa.tls.certresolver=bs"
- "traefik.http.middlewares.tfa.forwardauth.address=http://tfa:4181"
- "traefik.http.middlewares.tfa.forwardauth.authResponseHeaders=X-Forwarded-User"
- "traefik.http.services.tfa.loadbalancer.server.port=4181"
- "traefik.http.routers.tfa.middlewares=tfa"
This works great in icognito, fails in already logged in session.
That sounds to me like a cookie issue. I have seen it when my cookie domain or auth host were wrong. It can also be related to SSL if you are setting insecure cookies - I.e. if a proxy is terminating SSL and traefik-forward-auth is listening HTTP. Make sure to set the X-Forwarded-Porto: https header in cases like this.
Alternatively I would debug the auth request that returns a set-cookie response and then the “Not Authorized” request and what cookies are set for it / in your browser. There is likely a mismatch.
Hope that helps!
Sent from my iPhone
On Dec 30, 2020, at 4:23 PM, Nishant Arora [email protected] wrote:
I am getting a similar error, works in a new session but fails when already logged in:
time="2020-12-30T21:13:47Z" level=warning msg="Error validating csrf cookie" csrf_cookie="_forward_auth_csrf=
tfa:
image: thomseddon/traefik-forward-auth:2-arm
environment:
- PROVIDERS_GOOGLE_CLIENT_ID=${GOOGLE_CLIENT_ID}
- PROVIDERS_GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET}
- SECRET=${AUTH_JWT_SECRET}
- COOKIE_DOMAIN=${BS_URL} #sub domain
- AUTH_HOST=auth.${BS_URL}
- LOG_LEVEL=${LOG_LEVEL}
- WHITELIST=${WHITELIST}
labels:
- "traefik.enable=true"
- "traefik.http.routers.tfa.rule=Host(auth.${BS_URL}
)"
- "traefik.http.routers.tfa.entrypoints=websecure"
- "traefik.http.routers.tfa.service=tfa"
- "traefik.http.routers.tfa.tls.certresolver=bs"
- "traefik.http.middlewares.tfa.forwardauth.address=http://tfa:4181"
- "traefik.http.middlewares.tfa.forwardauth.authResponseHeaders=X-Forwarded-User"
- "traefik.http.services.tfa.loadbalancer.server.port=4181"
- "traefik.http.routers.tfa.middlewares=tfa"
This works great in icognito, fails in already logged in session.
— You are receiving this because you commented. Reply to this email directly, view it on GitHubhttps://github.com/thomseddon/traefik-forward-auth/issues/198#issuecomment-752762816, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AFQBVVUWETI7734IUCCYAR3SXOK6RANCNFSM4SSOAPCQ.
I am having this same issue. It seems to be after a good 24 hours before users will see the issue. I am using AUTH_HOST and have double checked all the parameters are correct. Basically results in CSRF cookie does not match state
error
Not a smoking gun yet but it seems to happen only in Firefox and possibly related to having multiple Google accounts logged in.
I doubt this will help but FWIW:
This returns 401:
https://myauthhost.domain.net/_oauth?state=3ec2e130e45526c0e7f372621d4183a4:google:https://thingImAuthingTo.domain.net/&code=4/JIBBERISHAUTHSTUFFS&scope=email%20profile%20openid%20https://www.googleapis.com/auth/userinfo.profile%20https://www.googleapis.com/auth/userinfo.email&authuser=2&hd=domain.com&prompt=none
I can see the CSRF cookie clearly does not match the state value in the URL above. Happy to do a little more research if someone can hint me what to look for.
Note, my authhost is domain.net my email domain is domain.com (which is in the hd parameter of the URL)
Could it be that when you try to initially access the site, it sets the cookie but then redirects you to login, the login then sets a new cookie and after login it redirects you back to the original site which looks for the original cookie that does no longer match?
Perhaps after a login we need to clear the state value for the original login cookie?
time="2021-02-23T14:57:53Z" level=debug msg="Authenticating request" cookies="[domain_forward_auth_csrf=f583fc2753c7af47d6bd3176920a940d]" handler=Auth host=protected.domain.net method=GET proto=https rule=default source_ip=172.20.0.20 uri=/
time="2021-02-23T14:57:53Z" level=debug msg="Set CSRF cookie and redirected to provider login url" csrf_cookie="domain_forward_auth_csrf=a0a3c823122e4837b9c82f00f701c783; Path=/; Domain=domain.net; Expires=Wed, 24 Feb 2021 02:57:53 GMT; HttpOnly; Secure" handler=Auth host=protected.domain.net login_url="https://accounts.google.com/o/oauth2/auth?client_id=945201490766-n2g8007g10cpnqeh6e1q3huo2i0kpat8.apps.googleusercontent.com&prompt=select_account&redirect_uri=https%3A%2F%2Fauth.domain.net%2F_oauth&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&state=a0a3c823122e4837b9c82f00f701c783%3Agoogle%3Ahttps%3A%2F%2Fprotected.domain.net%2F" method=GET proto=https rule=default source_ip=172.20.0.20 uri=/
time="2021-02-23T14:57:54Z" level=debug msg="Authenticating request" cookies="[domain_forward_auth_csrf=a0a3c823122e4837b9c82f00f701c783]" handler=Auth host=protected.domain.net method=GET proto=https rule=default source_ip=172.20.0.20 uri=/pwa-worker.js
time="2021-02-23T14:57:54Z" level=debug msg="Set CSRF cookie and redirected to provider login url" csrf_cookie="domain_forward_auth_csrf=194fbda8cf424dd18275495cb423c489; Path=/; Domain=domain.net; Expires=Wed, 24 Feb 2021 02:57:54 GMT; HttpOnly; Secure" handler=Auth host=protected.domain.net login_url="https://accounts.google.com/o/oauth2/auth?client_id=945201490766-n2g8007g10cpnqeh6e1q3huo2i0kpat8.apps.googleusercontent.com&prompt=select_account&redirect_uri=https%3A%2F%2Fauth.domain.net%2F_oauth&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&state=194fbda8cf424dd18275495cb423c489%3Agoogle%3Ahttps%3A%2F%2Fprotected.domain.net%2Fpwa-worker.js" method=GET proto=https rule=default source_ip=172.20.0.20 uri=/pwa-worker.js
time="2021-02-23T14:57:55Z" level=debug msg="Handling callback" cookies="[domain_forward_auth_csrf=194fbda8cf424dd18275495cb423c489]" handler=AuthCallback host=auth.domain.net method=GET proto=https rule=default source_ip=172.20.0.2 uri="/_oauth?state=a0a3c823122e4837b9c82f00f701c783:google:https://protected.domain.net/&code=4/0AY0e-g5KgF7b0rCDjCPk3faGMP0Dh7LvnyX9HGDenazvgG5aFxO4rfqy1hrgIwEG8HQLBQ&scope=email%20profile%20https://www.googleapis.com/auth/userinfo.profile%20https://www.googleapis.com/auth/userinfo.email%20openid&authuser=1&hd=domain.com&prompt=none"
time="2021-02-23T14:57:55Z" level=warning msg="Error validating csrf cookie" csrf_cookie="domain_forward_auth_csrf=194fbda8cf424dd18275495cb423c489" error="CSRF cookie does not match state" handler=AuthCallback host=auth.domain.net method=GET proto=https rule=default source_ip=172.20.0.2 uri="/_oauth?state=a0a3c823122e4837b9c82f00f701c783:google:https://protected.domain.net/&code=4/JIBBERISH&scope=email%20profile%20https://www.googleapis.com/auth/userinfo.profile%20https://www.googleapis.com/auth/userinfo.email%20openid&authuser=1&hd=domain.com&prompt=none"
Yeah, it looks like when you try to redirect the second time presumably from the middleware being on the auth endpoint, it sets a new cookie but the callback from Google comes back with the first state value and not the state you used when you redirect the second time.
Could you potentially fix this by not setting a new cookie when the host it is hitting is the AUTH_HOST?
Okay... I am going farther down the rabbit hole here.... The issue appears to be that the service I am protecting behind the proxy (Jitsi Meet in this case) has a Progressive Web App worker. When I attempt to access the web page, it works correctly. The problem is that the browser immediately tries to also connect the progressive web-app javascript. This generates another request which is then also redirected by traefik-forward-auth but it also changes my cookie again such that when the original web request comes back, it does not match. I think the correct way forward here will to be to whitelist the progressive web app javascript so it does not hit TFA.
Edit: Confirmed... that fixed it...
I also stumbled about the problem @snowzach mentioned: Firefox and Safari (both in Non-incognito-mode) seem to request additional resources from the secured domain, without being explicitly asked for, so the CSRF cookie is being overridden and the returning original request from upstream OIDC provider will fail with
time="2021-04-06T13:45:56Z" level=warning msg="Error validating csrf cookie" csrf_cookie="_forward_auth_csrf=<RETRACTED>" error="CSRF cookie does not match state" handler=AuthCallback host=<RETRACTED> method=GET proto=https rule=default source_ip=10.0.0.2 uri="/_oauth?code=<RETRACTED>&state=<RETRACTED>"
Chrome is working fine though.
Hi, I also had this issue, which thanks to @snowzach and @slinstaedt I realized my config was working fine on a browser other than firefox, but I also realized that the latest
tag is a lot more recent than the tag 2
which I was using before, not sure which version it contains, so I tried it out and I don't have this issue anymore.
So if this comment can help it seems the tag latest
is different than all the latest version tagged, unlike what is usually used with docker image.
Using latest
image instead of 2
did the trick for me. With the 2
image I have infinite loop redirecting