CSRF validation failure when running in docker
See original GitHub issueI have a flask / authlib client which works perfectly when run on localhost from the shell, but which consistently fails with a CSRF state-mismatch when run in a docker container. I put up a stackexchange question a couple of days ago which narrates the problem in more detail.
this may well not be an authlib problem, but my minimal example is very minimal and the problem is cropping up in authlib, so this seemed like the best place to report. apologies if that’s in error.
Error Stacks
Traceback (most recent call last):
File "/usr/local/lib64/python3.8/site-packages/flask/app.py", line 2464, in __call__
return self.wsgi_app(environ, start_response)
File "/usr/local/lib64/python3.8/site-packages/flask/app.py", line 2450, in wsgi_app
response = self.handle_exception(e)
File "/usr/local/lib64/python3.8/site-packages/flask/app.py", line 1867, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib64/python3.8/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/usr/local/lib64/python3.8/site-packages/flask/app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib64/python3.8/site-packages/flask/app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib64/python3.8/site-packages/flask/app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib64/python3.8/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/usr/local/lib64/python3.8/site-packages/flask/app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib64/python3.8/site-packages/flask/app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/app/src/app/flask_interface/user.py", line 17, in auth_callback
token = extensions.auth0.authorize_access_token()
File "/usr/local/lib/python3.8/site-packages/authlib/integrations/flask_client/remote_app.py", line 74, in authorize_access_token
params = self.retrieve_access_token_params(flask_req, request_token)
File "/usr/local/lib/python3.8/site-packages/authlib/integrations/base_client/base_app.py", line 149, in retrieve_access_token_params
params = self._retrieve_oauth2_access_token_params(request, params)
File "/usr/local/lib/python3.8/site-packages/authlib/integrations/base_client/base_app.py", line 130, in _retrieve_oauth2_access_token_params
raise MismatchingStateError()
To Reproduce
A minimal example can be found here. It should be possible to reproduce it by registering an oauth2 client and adding the client configuration to the code.
Expected behavior
Authentication should succeed when the client is run in a docker container.
Environment:
- OS: Fedora 32
- Python Version: 3.8.3
- Authlib Version: 0.14.3
Additional context
The docker environment is based on python:slim in the code examples above, but I have tested this with a dockerfile based on the fedora:latest package with the same result.
The problem seems to arise from non-persistence of the session between the setting of session[_auth0_authlib_state_]
before the login attempt and its getting when the callback is fired. Here’s some pertinent logging:
inside set_session_data:
request: <Request 'http://localhost:5000/login' [GET]>
key: state,
value: w4SnGtxMsOrledSvTHg3YzXkwCItHU
sess_key: _auth0_authlib_state_.
setting session[_auth0_authlib_state_] to w4SnGtxMsOrledSvTHg3YzXkwCItHU
session:[_auth0_authlib_state_]: w4SnGtxMsOrledSvTHg3YzXkwCItHU
inside app.flask_interface.user.auth_callback
inside _retrieve_oath2_access_token_params
inside get_session_data:
request: <Request 'http://localhost:5000/auth_callback?code=Sssrq1Yun_qhHkk4&state=w4SnGtxMsOrledSvTHg3YzXkwCItHU' [GET]>
key_param: state
generated session key: _auth0_authlib_state_
getting session.pop(_auth0_authlib_state_, None): no such key
back in app.flask_interface.user.auth_callback
request_state: w4SnGtxMsOrledSvTHg3YzXkwCItHU,
state: None
Issue Analytics
- State:
- Created 3 years ago
- Comments:5 (1 by maintainers)
Top GitHub Comments
If it’s just a “handful” I’m sure it’s not the same problem, but here’s the write-up:
In my case it was a misuse of the docker
--env-file
protocol deriving from unfamiliarity. I was using it as a direct proxy for a bash init script, but--env-file
doesn’t handle quotes in the same way as bash: “There is no special handling of quotation marks. This means that they are part of the VAL.” A beginner’s error!The result was that in the docker environment
os.getenv('VAR')
was getting VALs looked like"VAL"
; this was the case for, inter alia,SESSION_KEY="VAL"
andSESSION_COOKIE_NAME="VAL"
. Different libraries seemed to be handling these values differently, because I ended up with two cookies per session: one called"session_app"
and the other calledsession_app
. It’s no surprise that things broke!@circius thanks for the reply!