From e2b00dda1b15a1793f365544fce2c46e47b7a47e Mon Sep 17 00:00:00 2001 From: Aditya Toshniwal Date: Mon, 19 Sep 2022 15:36:10 +0530 Subject: [PATCH] Fixes a redirect vulnerability when the user opens the pgAdmin URL. Fixes #5343 --- docs/en_US/release_notes_6_14.rst | 1 + web/pgadmin/authenticate/__init__.py | 7 +++---- web/pgadmin/authenticate/oauth2.py | 9 ++++----- web/pgadmin/utils/__init__.py | 14 +++++++++++++- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/docs/en_US/release_notes_6_14.rst b/docs/en_US/release_notes_6_14.rst index a226bbe36..cac4f1213 100644 --- a/docs/en_US/release_notes_6_14.rst +++ b/docs/en_US/release_notes_6_14.rst @@ -44,3 +44,4 @@ Bug fixes | `Issue #5323 `_ - Replace the language selection 'Brazilian' with 'Portuguese (Brazilian). (RM #7693) | `Issue #5325 `_ - Fixed an issue where server names with special characters are not displayed correctly in the process tab. (RM #7695) | `Issue #5333 `_ - Fixed an issue where ERD throws an error if variable is added to the column. (RM #7709) + | `Issue #5343 `_ - Fixes a redirect vulnerability when the user opens the pgAdmin URL. diff --git a/web/pgadmin/authenticate/__init__.py b/web/pgadmin/authenticate/__init__.py index d637e32dd..a678ec480 100644 --- a/web/pgadmin/authenticate/__init__.py +++ b/web/pgadmin/authenticate/__init__.py @@ -16,11 +16,10 @@ from flask import current_app, flash, Response, request, url_for, \ session, redirect from flask_babel import gettext from flask_security.views import _security -from flask_security.utils import get_post_logout_redirect, \ - get_post_login_redirect, logout_user +from flask_security.utils import get_post_logout_redirect, logout_user from pgadmin.model import db, User -from pgadmin.utils import PgAdminModule +from pgadmin.utils import PgAdminModule, get_safe_post_login_redirect from pgadmin.utils.constants import KERBEROS, INTERNAL, OAUTH2, LDAP from pgadmin.authenticate.registry import AuthSourceRegistry @@ -145,7 +144,7 @@ def login(): if 'auth_obj' in session: session.pop('auth_obj') - return redirect(get_post_login_redirect()) + return redirect(get_safe_post_login_redirect()) elif isinstance(msg, Response): return msg diff --git a/web/pgadmin/authenticate/oauth2.py b/web/pgadmin/authenticate/oauth2.py index 07d398380..ea9a16c6b 100644 --- a/web/pgadmin/authenticate/oauth2.py +++ b/web/pgadmin/authenticate/oauth2.py @@ -16,14 +16,13 @@ from flask import current_app, url_for, session, request,\ redirect, Flask, flash from flask_babel import gettext from flask_security import login_user, current_user -from flask_security.utils import get_post_logout_redirect, \ - get_post_login_redirect, logout_user +from flask_security.utils import get_post_logout_redirect, logout_user from pgadmin.authenticate.internal import BaseAuthentication from pgadmin.model import User from pgadmin.tools.user_management import create_user from pgadmin.utils.constants import OAUTH2 -from pgadmin.utils import PgAdminModule +from pgadmin.utils import PgAdminModule, get_safe_post_login_redirect from pgadmin.utils.csrf import pgCSRFProtect from pgadmin.model import db @@ -58,12 +57,12 @@ def init_app(app): session['auth_source_manager'] = auth_obj.as_dict() if 'auth_obj' in session: session.pop('auth_obj') - return redirect(get_post_login_redirect()) + return redirect(get_safe_post_login_redirect()) if 'auth_obj' in session: session.pop('auth_obj') logout_user() flash(msg, 'danger') - return redirect(get_post_login_redirect()) + return redirect(get_safe_post_login_redirect()) @blueprint.route('/logout', endpoint="logout", methods=['GET', 'POST']) diff --git a/web/pgadmin/utils/__init__.py b/web/pgadmin/utils/__init__.py index 226c79b95..97c91a419 100644 --- a/web/pgadmin/utils/__init__.py +++ b/web/pgadmin/utils/__init__.py @@ -14,9 +14,10 @@ import subprocess from collections import defaultdict from operator import attrgetter -from flask import Blueprint, current_app +from flask import Blueprint, current_app, url_for from flask_babel import gettext from flask_security import current_user, login_required +from flask_security.utils import get_post_login_redirect from threading import Lock from .paths import get_storage_directory @@ -831,3 +832,14 @@ class KeyManager: if user is not None: del self.users[current_user.id] + + +def get_safe_post_login_redirect(): + allow_list = [ + url_for('browser.index') + ] + url = get_post_login_redirect() + if url in allow_list: + return url + + return "/"