puiterwijk/flask-oidc

Missing CSRF in session when authentication agains Keycloack

carleshf opened this issue · 4 comments

Bug description

There is no CSRF set on session, then the _process_callback is failing when checking:

if csrf_token != session_csrf_token:
    logger.debug("CSRF token mismatch")
    return True, self._oidc_error()

To Reproduce

Minimal python code for a flask server to reproduce the error:

#!/usr/bin/env python

import jwt
import logging
from flask import Flask, request, redirect, render_template
from flask_cors import CORS
from flask_oidc import OpenIDConnect

logging.basicConfig(level=logging.DEBUG)
app = Flask(__name__, static_url_path = '/static')
app.config.from_pyfile('main_config.py')
app.config.update({
    'DEBUG': True,
    'TESTING': True,
    'SECRET_KEY': 'test',
    'OIDC_CLIENT_SECRETS': 'client_secrets.json',
    'OIDC_ID_TOKEN_COOKIE_SECURE': False,
    'OIDC_REQUIRE_VERIFIED_EMAIL': False,
    'IDC_VERIFY_SSL': False
})
oidc = OpenIDConnect(app)
cors = CORS(app, resources={r"*": {"origins": "*"}})

@app.route('/')
def index():
    return render_template('welcome.html')

@app.route('/admin')
@oidc.require_login
def admin():
    info = oidc.user_getinfo(['email', 'openid_id', 'group'])
    return ('Hello, %s (%s)! <a href="/">Return</a>' %
            (info.get('email'), info.get('openid_id')))

@app.route('/logout')
def logout():
    oidc.logout()
    return redirect("/", code=302)

if __name__ == '__main__':
    app.run(host = '0.0.0.0', port = 5000, debug = True, threaded = True)

The welcome.html has a form with a link to the "admin" page, wich needs authentication:

<div class="d-flex justify-content-between align-items-center">
	<a href="{{ url_for('admin') }}" class="badge badge-secondary">Go!</a>
</div>

Expected behavior

I think that, somehow, before therequire_login the library should set a CSRF token in session used by _process_callback.

Screenshots

  • Screenshot-1: Checking the content of both csrf_token and session_csrf_token.
    Screenshot-1

  • Screenshot-2: Location of the breakpoint in flask_oidc:
    Screenshot-2

Desktop:

  • OS: Mac OS 10.11.6
  • Browser firefox
  • Version 81.0
  • Stack:
    • cryptography==2.9.2
    • Flask==1.1.2
    • Flask-Cors==3.0.8
    • Flask-Login==0.5.0
    • flask-oidc==1.4.0
    • flask-restplus==0.13.0
    • httplib2==0.18.1
    • oauth2client==4.1.3
    • PyJWT==1.6.4
    • requests==2.23.0
    • rsa==4.6
    • urllib3==1.25.9
    • Werkzeug==0.16.1
P-T-I commented

@carleshf Facing a similar issue... Did you ever came up with a work-around?

P-T-I commented

Thanks for your swift reply!

Hello @carleshf @P-T-I

I had the same problem. I solved it because it keycloak generate cookie (from an other domain) and my cookie policy was same-site="strict.

So, try to set Same-Site to None ?