From b714d8db93abff4dd0cd1763c88ac755dc6c20db Mon Sep 17 00:00:00 2001 From: Kyle Mahan Date: Sun, 31 May 2015 09:16:40 -0700 Subject: [PATCH] do not cache endpoints Caching these would have allowed a malicious or buggy auth/token_endpoint combination to give you credentials for another user's domain name. --- CHANGELOG.md | 11 +++++++++++ flask_micropub.py | 18 ++++-------------- setup.py | 2 +- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d79b2df..98ca28d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,17 @@ # Change Log All notable changes to this project will be documented in this file. +## 0.2.2 +## Changed +- Fix vulnerability; re-discover the authorization_endpoint and + token_endpoint at each stage in the flow. Prevents a buggy or + malicious authorization_endpoint from giving you credentials for + another user's domain name. + +## 0.2.1 - 2015-02-07 +## Changed +- Updated setup.py, no functional changes + ## 0.2.0 - 2015-02-07 ### Changed - Started keeping a changelog! diff --git a/flask_micropub.py b/flask_micropub.py index 85aabd0..7e7bf8b 100644 --- a/flask_micropub.py +++ b/flask_micropub.py @@ -121,10 +121,6 @@ class MicropubClient: csrf_token = uuid.uuid4().hex flask.session['_micropub_csrf_token'] = csrf_token - # save the endpoints so we don't have to scrape the target page again - # right awway - flask.session['_micropub_endpoints'] = ( - auth_url, token_url, micropub_url) auth_params = { 'me': me, @@ -165,6 +161,7 @@ class MicropubClient: def _handle_authenticate_response(self): code = flask.request.args.get('code') state = flask.request.args.get('state') + me = flask.request.args.get('me') redirect_uri = flask.url_for(flask.request.endpoint, _external=True) if state and '|' in state: @@ -180,11 +177,7 @@ class MicropubClient: return AuthResponse( next_url=next_url, error='mismatched CSRF token') - if '_micropub_endpoints' in flask.session: - auth_url = flask.session['_micropub_endpoints'][0] - else: - auth_url = self._discover_endpoints( - flask.request.args.get('me'))[0] + auth_url = self._discover_endpoints(me)[0] if not auth_url: return AuthResponse( @@ -227,16 +220,13 @@ class MicropubClient: authenticate_response = self._handle_authenticate_response() code = flask.request.args.get('code') state = flask.request.args.get('state') + me = flask.request.args.get('me') redirect_uri = flask.url_for(flask.request.endpoint, _external=True) if authenticate_response.error: return authenticate_response - if '_micropub_endpoints' in flask.session: - _, token_url, micropub_url = flask.session['_micropub_endpoints'] - else: - _, token_url, micropub_url = self._discover_endpoints( - flask.request.args.get('me')) + token_url, micropub_url = self._discover_endpoints(me)[1:] if not token_url or not micropub_url: # successfully auth'ed user, no micropub endpoint diff --git a/setup.py b/setup.py index b080121..d64ed7f 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ from setuptools import setup setup( name='Flask-Micropub', - version='0.2.0', + version='0.2.2', url='https://github.com/kylewm/flask-micropub/', license='BSD', author='Kyle Mahan',