-
-
Notifications
You must be signed in to change notification settings - Fork 467
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CSRF Warning! State not equal in request and response #376
Comments
I have the same issue and error stack trace, but use google oidc. Environment
|
@dnskr did you get this error with Authlib 1.0.0a2 ? How to reproduce it? I should have fixed this case in 1.0.0. |
I am also getting I used both 0.15.4 and 1.0.0a2 version of Authlib. if settings.BACKEND_CORS_ORIGINS:
app.add_middleware(SessionMiddleware, secret_key=settings.SECRET_KEY)
app.add_middleware(
CORSMiddleware,
allow_origins=[str(origin) for origin in settings.BACKEND_CORS_ORIGINS],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
config = Config(".env")
oauth = OAuth(config)
oauth.register(
name="gitlab",
client_id=settings.GITLAB_CLIENT_ID,
client_secret=settings.GITLAB_CLIENT_SECRET,
authorize_url="https://gitlab.com/oauth/authorize",
client_kwargs={"scope": "read_user+profile"},
)
@app.get("/auth/gitlab")
async def auth_gitlab(request: Request):
print("###################")
print("request", request, request.session)
# {'_gitlab_authlib_redirect_uri_': 'http://localhost:8888/auth/gitlab'}
gitlab = oauth.create_client("gitlab")
try:
token = await gitlab.authorize_access_token(request)
print("token", token)
user = await gitlab.parse_id_token(request, token)
print("user", dict(user))
return {"token": token}
except OAuthError as error:
print("oauth error", error, error.error) From frontend the following url is hit once authorize button is clicked to reach to /auth/gitlab function as I have used
my oauth url for the popup is
UPDATE: {'_state_gitlab_WiBjFgSNd5BV1A7hlDHX0': {'data': {'redirect_uri': 'http://localhost:8888/auth/gitlab', 'url': 'https://gitlab.com/oauth/authorize?response_type=code&client_id=e2dc9edc72dbcf5524910eca1d0577473b6005a833c97&redirect_uri=http%3A%2F%2Flocalhost%3A8888%2Fauth%2Fgitlab&scope=read_user%2Bprofile&state=WiBjFgSNd5BV1A7hlDHX0'}, 'exp': 1632275167.3455658}, '_state_gitlab_3YUfQJ4ubbNjErkqY4dJ7ZQMzzmCqt': {'data': {'redirect_uri': 'http://localhost:8888/auth/gitlab', 'url': 'https://gitlab.com/oauth/authorize?response_type=code&client_id=e2dc9edc72dbcf5524910eca1d0577473b6005a833c97&redirect_uri=http%3A%2F%2Flocalhost%3A8888%2Fauth%2Fgitlab&scope=read_user%2Bprofile&state=3YUfQJ4ubbNjErkqY4dJ7ZQMzzmCqt'}, 'exp': 1632275280.9188702}, '_state_gitlab_S3OQ93EDvralFGYiu5HxRWxUMWZFQh': {'data': {'redirect_uri': 'http://localhost:8888/auth/gitlab', 'url': 'https://gitlab.com/oauth/authorize?response_type=code&client_id=e2dc9edc72dbcf5524910eca1d0577473b6005a833c97&redirect_uri=http%3A%2F%2Flocalhost%3A8888%2Fauth%2Fgitlab&scope=read_user%2Bprofile&state=S3OQ93EDvralFGYiu5HxRWxUMWZFQh'}, 'exp': 1632275404.760191}, '_state_gitlab_vImiUiWK4VIUL82PywWlIZ1K9yA5Ss': {'data': {'redirect_uri': 'http://localhost:8888/auth/gitlab', 'url': 'https://gitlab.com/oauth/authorize?response_type=code&client_id=e2dc9edc72dbcf5524910eca1d0577473b6005a833c97&redirect_uri=http%3A%2F%2Flocalhost%3A8888%2Fauth%2Fgitlab&scope=read_user%2Bprofile&state=vImiUiWK4VIUL82PywWlIZ1K9yA5Ss'}, 'exp': 1632275509.933466}} When I changed oauth_url for pop up to const oauthUrl = `${GITLAB_URL}/oauth/authorize?client_id=${client_id}&response_type=code&scope=${scope}&state=${
state + 'WiBjFgSNd5BV1A7hlDHX0'
}&redirect_uri=${redirect_uri}&allow_signup=${allow_signup}` I get I am using fastapi |
@lepture I tried your fastapi example and it is not working as well. Although, I am using gitlab instead of google. I am getting |
For your case, I see
The And for:
This is caused by not specifying |
edit: I've found the issue in our case: the regression was introduced in our own code (session was reset between requests). You can ignore this comment, authlib is still working as expected for us. |
@jerome-poisson , I am encountering an issue similar to yours. I noticed that the session is being reset between requests which leads to this mismatch error. Do you know how I can sort out the session resetting? In my case, the second request is the call back which has different data in the flask session, so I am not sure where authlib is updating the session values. |
hi @nikhil003 the issue was on our side with cookie management, and at the end it was not a problem with authlib as I was initially suspecting. Thus there is little I can do here, sorry. |
Encountering the same issue. What's the solution?? |
same |
Previously, I would get a state issue from #419 on Starlette. This seems to be the problem I am running into now. |
After some further investigation: The easiest way for me to consistently reproduce this is to use Google OIDC, and this happens after the 5th continuous re-authentication. It seems as if during these cases,
Which led me to check the I can see that there is functionality for adding your own cache mechanism to the I'm not too familiar with the flow, but it would seem intuitive to me to clear the state from the session once it has been authenticated via For what it is worth, this behavior already happens in the OAuth1 flow:
|
I've put up a PR to fix this behavior: #428 |
Did the issue get fixed. |
1.0.0 was released. |
@lepture Hi there! I've tried the 1.0.0 version just now, and it seems the issue persists with Google Oauth2. oauth = OAuth()
oauth.register(
name='google',
server_metadata_url='https://accounts.google.com/.well-known/openid-configuration',
client_kwargs={
'scope': 'openid email profile'
},
client_id=GOOGLE_OAUTH2_CLIENT_ID,
client_secret=GOOGLE_OAUTH2_CLIENT_SECRET
)
@app.route('/oauth2-login')
async def oauth2_login(request: Request):
# absolute url for callback
# we will define it below
redirect_uri = request.url_for('oauth2_auth')
return await oauth.google.authorize_redirect(request, redirect_uri)
@app.route('/oauth2-auth')
async def oauth2_auth(request: Request):
token = await oauth.google.authorize_access_token(request)
user = token['userinfo']
return user My stacktrace :
|
@sorasful try clearing the session cookie and try again. If you use the session cookie for other things, that may also be causing problems. |
The issue is not exactly fixed. As said before the issue happens when the session cookie is larger than 4096 bytes. The major culprit at the moment is the fact the URI to fetch the authorization code is inserted into the session cookie for no reason, I think removing it will help to reduce the number of people facing this issue |
@oribs1 the saved URI is |
I also experience this issue with the latest version of Authlib and Google auth. This happens when I am testing on my phone and I go from mobile to desktop view as well as occasionally with my laptop, depending on how many times I re-auth. |
Some info here, I solved it for myself, leaving this here in case anyone needs it. The issue seems to originate because the "state" the auth provider provides mismatches the "state" that authlib tries to retrieve from the session. ie, authlib generates a "state" string, then it stores it in the Flask session: It puts the state string into a query string it passes to the auth provider (ie, to Google or whatever): After auth, the auth provider redirects the user back to your authentication endpoint (preferably with the state param): Then authlib checks the session for the state string:
So, to fix this, there are a couple of possible areas this could break. I'm a bit rusty at how Flask works in entirety, but some avenues to look into:
For me personally, I had to set |
This issue still persists using Azure OAuth 2.0 on Airflow 2.4.3 and these tool versions: Python 3.8.15 The only thing we get in our logs is: Have used the network debug tool in Chrome to look at the url's being sent and it looks like the same state is being sent in the request and the response, but it just brings us back to the login page every time and throws this error. |
Encountered this issue. Our auth flow is as follows: After hitting step 2, when the client is sent back to the Auth server, we were seeing 400: Bad request. Viewing the logs for the service was revealing the error "CSRF Warning..." To fix it, when I saw the 400: Bad Request, I cleared the cookies in Chrome for that URL. I also cleared the client web application's cookies. Then the authorisation was allowed to proceed without any CSRF errors. It seems something cookie is not cleared even when sending new authorisation requests. |
I encountered the CSRF mismatch error when an user is using the back button after logging in. In the following example client the user is redirected to the However, authlib is clearing the CSRF token right after authentication process: As a result you will receive a CSRF mismatch error. To prevent this in my application, it was necessary to check whether a session exists before creating a new one; @app.route('/auth')
def auth():
if "user" in session:
token = oauth.google.authorize_access_token()
session['user'] = token['userinfo']
return redirect('/') |
Like I've mentionned in #334 and encode/starlette#2019, a common cause for this bug (for me) comes from a Chrome + Starlette issue where Starlette handles session storage as more or less a JWT and will include a new The issue is reproduced like so:
There seems to be several other ways in which this error message can be triggered, though. |
Describe the bug
It happens when using authlib to configure Keycloak for Apache Superset. Everything works perfectly up until redirecting back from Keycloak to Superset.
Error Stacks
To Reproduce
A minimal example to reproduce the behavior:
This is my code:
In
superset_config.py
In
extended_security.py
Expected behavior
Suerpset redirect user to keycloak authentication site as expected. Upon finishing authenticating and getting redirected back to superset,
CSRF Warning! State not equal in request and response
occur.Environment:
Docker:
3.8
0.15.4
Additional context
Tried on different browser (chrome, firefox, edge, etc.), clearing cookies, etc., but the error is still there.
Would very appreciate some help.
The text was updated successfully, but these errors were encountered: