Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-Flask-Security-Too for openSUSE:Factory checked in at 2024-01-07 21:39:58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-Flask-Security-Too (Old) and /work/SRC/openSUSE:Factory/.python-Flask-Security-Too.new.28375 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-Flask-Security-Too" Sun Jan 7 21:39:58 2024 rev:21 rq:1137307 version:5.3.3 Changes: -------- --- /work/SRC/openSUSE:Factory/python-Flask-Security-Too/python-Flask-Security-Too.changes 2024-01-06 17:29:27.076220786 +0100 +++ /work/SRC/openSUSE:Factory/.python-Flask-Security-Too.new.28375/python-Flask-Security-Too.changes 2024-01-07 21:40:14.687893596 +0100 @@ -1,0 +2,9 @@ +Sat Jan 6 20:55:19 UTC 2024 - Matej Cepl <mc...@cepl.eu> + +- Update to 5.3.3: + Fix for CVE-2023-49438 (bsc#1218412). +- Refresh patches: + - no-mongodb.patch + - use-pyqrcodeng.patch + +------------------------------------------------------------------- Old: ---- Flask-Security-Too-5.3.2.tar.gz New: ---- Flask-Security-Too-5.3.3.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-Flask-Security-Too.spec ++++++ --- /var/tmp/diff_new_pack.hMEQuh/_old 2024-01-07 21:40:15.575925898 +0100 +++ /var/tmp/diff_new_pack.hMEQuh/_new 2024-01-07 21:40:15.575925898 +0100 @@ -18,7 +18,7 @@ %{?sle15_python_module_pythons} Name: python-Flask-Security-Too -Version: 5.3.2 +Version: 5.3.3 Release: 0 Summary: Security for Flask apps License: MIT ++++++ Flask-Security-Too-5.3.2.tar.gz -> Flask-Security-Too-5.3.3.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Flask-Security-Too-5.3.2/CHANGES.rst new/Flask-Security-Too-5.3.3/CHANGES.rst --- old/Flask-Security-Too-5.3.2/CHANGES.rst 2023-10-24 04:21:35.000000000 +0200 +++ new/Flask-Security-Too-5.3.3/CHANGES.rst 2023-12-30 02:11:27.000000000 +0100 @@ -3,6 +3,16 @@ Here you can see the full list of changes between each Flask-Security release. +Version 5.3.3 +------------- + +Released December 29, 2023 + +Fixes ++++++ +- (:issue:`893`) Once again work on open-redirect vulnerability - this time due to newer Werkzeug. + Addresses: CVE-2023-49438 + Version 5.3.2 ------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Flask-Security-Too-5.3.2/Flask_Security_Too.egg-info/PKG-INFO new/Flask-Security-Too-5.3.3/Flask_Security_Too.egg-info/PKG-INFO --- old/Flask-Security-Too-5.3.2/Flask_Security_Too.egg-info/PKG-INFO 2023-10-24 04:22:41.000000000 +0200 +++ new/Flask-Security-Too-5.3.3/Flask_Security_Too.egg-info/PKG-INFO 2023-12-30 02:12:23.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: Flask-Security-Too -Version: 5.3.2 +Version: 5.3.3 Summary: Quickly add security features to your Flask application. Author: Matt Wright Author-email: Chris Wagner <jwag.wagner+git...@gmail.com> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Flask-Security-Too-5.3.2/PKG-INFO new/Flask-Security-Too-5.3.3/PKG-INFO --- old/Flask-Security-Too-5.3.2/PKG-INFO 2023-10-24 04:22:42.006616000 +0200 +++ new/Flask-Security-Too-5.3.3/PKG-INFO 2023-12-30 02:12:23.971362600 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: Flask-Security-Too -Version: 5.3.2 +Version: 5.3.3 Summary: Quickly add security features to your Flask application. Author: Matt Wright Author-email: Chris Wagner <jwag.wagner+git...@gmail.com> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Flask-Security-Too-5.3.2/docs/configuration.rst new/Flask-Security-Too-5.3.3/docs/configuration.rst --- old/Flask-Security-Too-5.3.2/docs/configuration.rst 2023-10-24 04:21:35.000000000 +0200 +++ new/Flask-Security-Too-5.3.3/docs/configuration.rst 2023-12-30 02:11:27.000000000 +0100 @@ -279,46 +279,27 @@ .. py:data:: SECURITY_REDIRECT_VALIDATE_MODE - These 2 configuration options attempt to solve a open-redirect vulnerability - that can be exploited if an application sets the Werkzeug response option - ``autocorrect_location_header = False`` (it is ``True`` by default). - For numerous views (e.g. /login) Flask-Security allows callers to specify - a redirect upon successful completion (via the ?next parameter). So it is - possible for a user to be tricked into logging in to a legitimate site - and then redirected to a malicious site. Flask-Security attempts to - verify that redirects are always relative to overcome this security concern. - FS uses the standard Python library urlsplit() to parse the URL and verify - that the ``netloc`` hasn't been altered. - However, many browsers actually accept URLs that should be considered - relative and perform various stripping and conversion that can cause them - to be interpreted as absolute. A trivial example of this is: - - .. line-block:: - /login?next=%20///github.com - - This will pass the urlsplit() test that it is relative - but many browsers - will simply strip off the space and interpret it as an absolute URL! - With the default configuration of Werkzeug this isn't an issue since it by - default modifies the Location Header to with the request ``netloc``. However - if the application sets the Werkzeug response option - ``autocorrect_location_header = False`` this will allow a redirect outside of - the application. - - Setting this to ``"regex"`` will force the URL to be matched using the - pattern specified below. If a match occurs the URL is considered 'absolute' - and will be rejected. + Defines how Flask-Security will attempt to mitigate an open redirect + vulnerability w.r.t. client supplied `next` parameters. + Please see :ref:`redirect_topic` for a complete discussion. - Default: ``None`` + Current options include `"absolute"` and `"regex"`. A list is allowed. + + + Default: ``["absolute"]`` .. versionadded:: 4.0.2 + .. versionchanged:: 5.3.3 + Default is now `"absolute"` and now takes a list. + .. py:data:: SECURITY_REDIRECT_VALIDATE_RE This regex handles known patterns that can be exploited. Basically, don't allow control characters or white-space followed by slashes (or back slashes). - Default: ``r"^/{4,}|\\{3,}|[\s\000-\037][/\\]{2,}"`` + Default: ``r"^/{4,}|\\{3,}|[\s\000-\037][/\\]{2,}(?![/\\])|[/\\]([^/\\]|/[^/\\])*[/\\].*"`` .. versionadded:: 4.0.2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Flask-Security-Too-5.3.2/docs/patterns.rst new/Flask-Security-Too-5.3.3/docs/patterns.rst --- old/Flask-Security-Too-5.3.2/docs/patterns.rst 2023-10-24 04:21:35.000000000 +0200 +++ new/Flask-Security-Too-5.3.3/docs/patterns.rst 2023-12-30 02:11:27.000000000 +0100 @@ -93,6 +93,60 @@ Flask-Security itself uses this as part of securing the :ref:`unified-sign-in`, :ref:`two-factor`, and :ref:`webauthn` setup endpoints. +.. _redirect_topic: + +Open Redirect Exposure +~~~~~~~~~~~~~~~~~~~~~~~ +Flask-Security, accepts a ``next=xx`` parameter (either +as a query param OR in the POSTed form) which it will use when completing an operation +which results in a redirection. If a malicious user/ +application can inject an arbitrary ``next`` parameter which redirects to an external +location, this results in a security vulnerability called an `open redirect`. +The following endpoints accept a ``next`` parameter:: + +- .login ("/login") +- .logout ("/logout") +- .register ("/register") +- .verify ("/verify") +- .two_factor_token_validation ("/tf-validate") +- .wan_verify_response ("/wan-verify") +- .wan_signin_response ("/wan-signin") +- .us_signin ("/us-signin") +- .us_verify ("/us-verify") + + +Flask-Security attempts to verify that redirects are always relative. +FS uses the standard Python library urlsplit() to parse the URL and verify +that the ``netloc`` hasn't been altered. +However, many browsers actually accept URLs that should be considered +relative and perform various stripping and conversions that can cause them +to be interpreted as absolute. A trivial example of this is: + +.. line-block:: + /login?next=%20///github.com + +This will pass the urlsplit() test that it is relative - but many browsers +will simply strip off the space and interpret it as an absolute URL! + +Prior to Werkzeug 2.1, Werkzeug set the response configuration variable +``autocorrect_location_header = True`` which forced the response `Location` +header to always be an absolute path - thus effectively squashing any open +redirect possibility. However since 2.1 it is now `False`. + +Flask Security offers +2 mitigations for this via the :py:data:`SECURITY_REDIRECT_VALIDATE_MODE` and +:py:data:`SECURITY_REDIRECT_VALIDATE_RE` configuration variables. + +- The first mode - `"absolute"`, which is the default, is to once again set Werkzeug's ``autocorrect_location_header`` + to ``True``. Please note that this is set JUST for Flask-Security's blueprint - not all requests. +- With the second mode - `"regex"` - FS uses a regular expression to validate all ``next`` parameters to make sure + they will be interpreted as `relative`. Be aware that the default regular + expression is based on in-the-field testing and it is quite possible that there + are other crafted relative URLs that could escape detection. + +:py:data:`SECURITY_REDIRECT_VALIDATE_MODE` actually takes a list - so both +mechanisms can be specified. + .. _pass_validation_topic: Password Validation and Complexity diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Flask-Security-Too-5.3.2/flask_security/__init__.py new/Flask-Security-Too-5.3.3/flask_security/__init__.py --- old/Flask-Security-Too-5.3.2/flask_security/__init__.py 2023-10-24 04:21:35.000000000 +0200 +++ new/Flask-Security-Too-5.3.3/flask_security/__init__.py 2023-12-30 02:11:27.000000000 +0100 @@ -134,4 +134,4 @@ ) from .webauthn_util import WebauthnUtil -__version__ = "5.3.2" +__version__ = "5.3.3" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Flask-Security-Too-5.3.2/flask_security/core.py new/Flask-Security-Too-5.3.3/flask_security/core.py --- old/Flask-Security-Too-5.3.2/flask_security/core.py 2023-10-24 04:21:35.000000000 +0200 +++ new/Flask-Security-Too-5.3.3/flask_security/core.py 2023-12-30 02:11:27.000000000 +0100 @@ -196,8 +196,8 @@ "REDIRECT_HOST": None, "REDIRECT_BEHAVIOR": None, "REDIRECT_ALLOW_SUBDOMAINS": False, - "REDIRECT_VALIDATE_MODE": None, - "REDIRECT_VALIDATE_RE": r"^/{4,}|\\{3,}|[\s\000-\037][/\\]{2,}", + "REDIRECT_VALIDATE_MODE": ["absolute"], + "REDIRECT_VALIDATE_RE": r"^/{4,}|\\{3,}|[\s\000-\037][/\\]{2,}(?![/\\])|[/\\]([^/\\]|/[^/\\])*[/\\].*", # noqa: E501 "FORGOT_PASSWORD_TEMPLATE": "security/forgot_password.html", "LOGIN_USER_TEMPLATE": "security/login_user.html", "REGISTER_USER_TEMPLATE": "security/register_user.html", @@ -1432,10 +1432,6 @@ self._username_util = self.username_util_cls(app) self._webauthn_util = self.webauthn_util_cls(app) self._mf_recovery_codes_util = self.mf_recovery_codes_util_cls(app) - rvre = cv("REDIRECT_VALIDATE_RE", app=app) - if rvre: - self._redirect_validate_re = re.compile(rvre) - self.remember_token_serializer = _get_serializer(app, "remember") self.login_serializer = _get_serializer(app, "login") self.reset_serializer = _get_serializer(app, "reset") @@ -1522,10 +1518,32 @@ if cv("OAUTH_ENABLE", app=app): self.oauthglue = OAuthGlue(app, self._oauth) + redirect_validate_mode = cv("REDIRECT_VALIDATE_MODE", app=app) or [] + if redirect_validate_mode: + # should be "regex" or "absolute" or a list of those + if not isinstance(redirect_validate_mode, list): + redirect_validate_mode = [redirect_validate_mode] + if all([m in ["regex", "absolute"] for m in redirect_validate_mode]): + if "regex" in redirect_validate_mode: + rvre = cv("REDIRECT_VALIDATE_RE", app=app) + if rvre: + self._redirect_validate_re = re.compile(rvre) + else: + raise ValueError("Must specify REDIRECT_VALIDATE_RE") + else: + raise ValueError("Invalid value(s) for REDIRECT_VALIDATE_MODE") + + def autocorrect(r): + # By setting this (Werkzeug) avoids any open-redirect issues. + r.autocorrect_location_header = True + return r + # register our blueprint/endpoints bp = None if self.register_blueprint: bp = create_blueprint(app, self, __name__) + if "absolute" in redirect_validate_mode: + bp.after_request(autocorrect) self.two_factor_plugins.create_blueprint(app, bp, self) if self.oauthglue: self.oauthglue._create_blueprint(app, bp) Binary files old/Flask-Security-Too-5.3.2/flask_security/translations/af_ZA/LC_MESSAGES/flask_security.mo and new/Flask-Security-Too-5.3.3/flask_security/translations/af_ZA/LC_MESSAGES/flask_security.mo differ Binary files old/Flask-Security-Too-5.3.2/flask_security/translations/ca_ES/LC_MESSAGES/flask_security.mo and new/Flask-Security-Too-5.3.3/flask_security/translations/ca_ES/LC_MESSAGES/flask_security.mo differ Binary files old/Flask-Security-Too-5.3.2/flask_security/translations/da_DK/LC_MESSAGES/flask_security.mo and new/Flask-Security-Too-5.3.3/flask_security/translations/da_DK/LC_MESSAGES/flask_security.mo differ Binary files old/Flask-Security-Too-5.3.2/flask_security/translations/de_DE/LC_MESSAGES/flask_security.mo and new/Flask-Security-Too-5.3.3/flask_security/translations/de_DE/LC_MESSAGES/flask_security.mo differ Binary files old/Flask-Security-Too-5.3.2/flask_security/translations/es_ES/LC_MESSAGES/flask_security.mo and new/Flask-Security-Too-5.3.3/flask_security/translations/es_ES/LC_MESSAGES/flask_security.mo differ Binary files old/Flask-Security-Too-5.3.2/flask_security/translations/eu_ES/LC_MESSAGES/flask_security.mo and new/Flask-Security-Too-5.3.3/flask_security/translations/eu_ES/LC_MESSAGES/flask_security.mo differ Binary files old/Flask-Security-Too-5.3.2/flask_security/translations/fr_FR/LC_MESSAGES/flask_security.mo and new/Flask-Security-Too-5.3.3/flask_security/translations/fr_FR/LC_MESSAGES/flask_security.mo differ Binary files old/Flask-Security-Too-5.3.2/flask_security/translations/hu_HU/LC_MESSAGES/flask_security.mo and new/Flask-Security-Too-5.3.3/flask_security/translations/hu_HU/LC_MESSAGES/flask_security.mo differ Binary files old/Flask-Security-Too-5.3.2/flask_security/translations/hy_AM/LC_MESSAGES/flask_security.mo and new/Flask-Security-Too-5.3.3/flask_security/translations/hy_AM/LC_MESSAGES/flask_security.mo differ Binary files old/Flask-Security-Too-5.3.2/flask_security/translations/is_IS/LC_MESSAGES/flask_security.mo and new/Flask-Security-Too-5.3.3/flask_security/translations/is_IS/LC_MESSAGES/flask_security.mo differ Binary files old/Flask-Security-Too-5.3.2/flask_security/translations/ja_JP/LC_MESSAGES/flask_security.mo and new/Flask-Security-Too-5.3.3/flask_security/translations/ja_JP/LC_MESSAGES/flask_security.mo differ Binary files old/Flask-Security-Too-5.3.2/flask_security/translations/nl_NL/LC_MESSAGES/flask_security.mo and new/Flask-Security-Too-5.3.3/flask_security/translations/nl_NL/LC_MESSAGES/flask_security.mo differ Binary files old/Flask-Security-Too-5.3.2/flask_security/translations/pl_PL/LC_MESSAGES/flask_security.mo and new/Flask-Security-Too-5.3.3/flask_security/translations/pl_PL/LC_MESSAGES/flask_security.mo differ Binary files old/Flask-Security-Too-5.3.2/flask_security/translations/pt_BR/LC_MESSAGES/flask_security.mo and new/Flask-Security-Too-5.3.3/flask_security/translations/pt_BR/LC_MESSAGES/flask_security.mo differ Binary files old/Flask-Security-Too-5.3.2/flask_security/translations/pt_PT/LC_MESSAGES/flask_security.mo and new/Flask-Security-Too-5.3.3/flask_security/translations/pt_PT/LC_MESSAGES/flask_security.mo differ Binary files old/Flask-Security-Too-5.3.2/flask_security/translations/ru_RU/LC_MESSAGES/flask_security.mo and new/Flask-Security-Too-5.3.3/flask_security/translations/ru_RU/LC_MESSAGES/flask_security.mo differ Binary files old/Flask-Security-Too-5.3.2/flask_security/translations/tr_TR/LC_MESSAGES/flask_security.mo and new/Flask-Security-Too-5.3.3/flask_security/translations/tr_TR/LC_MESSAGES/flask_security.mo differ Binary files old/Flask-Security-Too-5.3.2/flask_security/translations/zh_Hans_CN/LC_MESSAGES/flask_security.mo and new/Flask-Security-Too-5.3.3/flask_security/translations/zh_Hans_CN/LC_MESSAGES/flask_security.mo differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Flask-Security-Too-5.3.2/tests/test_common.py new/Flask-Security-Too-5.3.3/tests/test_common.py --- old/Flask-Security-Too-5.3.2/tests/test_common.py 2023-10-24 04:21:35.000000000 +0200 +++ new/Flask-Security-Too-5.3.3/tests/test_common.py 2023-12-30 02:11:27.000000000 +0100 @@ -22,6 +22,7 @@ from tests.test_utils import ( authenticate, capture_flashes, + check_location, get_auth_token_version_3x, get_form_action, get_num_queries, @@ -183,13 +184,13 @@ @pytest.mark.settings(username_enable=True, username_required=True) -def test_login_form_username_required(client): +def test_login_form_username_required(app, client): # If username required - we should still be able to login with email alone # given default user_identity_attributes response = client.post( "/login", data=dict(email="m...@lp.com", password="password") ) - assert response.location == "/" + assert check_location(app, response.location, "/") @pytest.mark.confirmable() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Flask-Security-Too-5.3.2/tests/test_confirmable.py new/Flask-Security-Too-5.3.3/tests/test_confirmable.py --- old/Flask-Security-Too-5.3.2/tests/test_confirmable.py 2023-10-24 04:21:35.000000000 +0200 +++ new/Flask-Security-Too-5.3.3/tests/test_confirmable.py 2023-12-30 02:11:27.000000000 +0100 @@ -22,6 +22,7 @@ authenticate, capture_flashes, capture_registrations, + check_location, is_authenticated, logout, populate_data, @@ -469,7 +470,7 @@ token = registrations[0]["confirm_token"] response = client.get("/confirm/" + token, follow_redirects=False) - assert "/postlogin" == response.location + assert check_location(app, response.location, "/postlogin") assert is_authenticated(client, get_message) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Flask-Security-Too-5.3.2/tests/test_misc.py new/Flask-Security-Too-5.3.3/tests/test_misc.py --- old/Flask-Security-Too-5.3.2/tests/test_misc.py 2023-10-24 04:21:35.000000000 +0200 +++ new/Flask-Security-Too-5.3.3/tests/test_misc.py 2023-12-30 02:11:27.000000000 +0100 @@ -25,6 +25,7 @@ authenticate, capture_flashes, capture_reset_password_requests, + check_location, check_xlation, get_csrf_token, init_app_with_options, @@ -1136,7 +1137,7 @@ response = client.post( verify_url, data=dict(password="password"), follow_redirects=False ) - assert response.location == "http://localhost/fresh" + assert check_location(app, response.location, "/fresh") # should be fine now response = client.get("/fresh", follow_redirects=True) @@ -1320,6 +1321,27 @@ assert "/post_logout" in response.location +def test_invalid_redirect_config(app, sqlalchemy_datastore, get_message): + with pytest.raises(ValueError): + init_app_with_options( + app, + sqlalchemy_datastore, + **{"SECURITY_REDIRECT_VALIDATE_MODE": ["regex", "bogus"]}, + ) + + +def test_invalid_redirect_re(app, sqlalchemy_datastore, get_message): + with pytest.raises(ValueError): + init_app_with_options( + app, + sqlalchemy_datastore, + **{ + "SECURITY_REDIRECT_VALIDATE_MODE": ["regex"], + "SECURITY_REDIRECT_VALIDATE_RE": None, + }, + ) + + @pytest.mark.settings(redirect_validate_mode="regex") def test_validate_redirect(app, sqlalchemy_datastore): """ @@ -1333,9 +1355,24 @@ assert not validate_redirect_url("\\\\\\github.com") assert not validate_redirect_url(" //github.com") assert not validate_redirect_url("\t//github.com") + assert not validate_redirect_url(r"/\github.com") + assert not validate_redirect_url(r"\/github.com") assert not validate_redirect_url("//github.com") # this is normal urlsplit +@pytest.mark.settings(post_login_view="\\\\\\github.com") +def test_validate_redirect_default(app, client): + """ + Test various possible URLs that urlsplit() shows as relative but + many browsers will interpret as absolute - and thus have a + open-redirect vulnerability. This tests the default configuration for + Flask-Security, Flask, Werkzeug + """ + authenticate(client) + response = client.get("/login", follow_redirects=False) + assert response.location.startswith("http://localhost") + + def test_kwargs(): import warnings diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Flask-Security-Too-5.3.2/tests/test_two_factor.py new/Flask-Security-Too-5.3.3/tests/test_two_factor.py --- old/Flask-Security-Too-5.3.2/tests/test_two_factor.py 2023-10-24 04:21:35.000000000 +0200 +++ new/Flask-Security-Too-5.3.3/tests/test_two_factor.py 2023-12-30 02:11:27.000000000 +0100 @@ -26,6 +26,7 @@ authenticate, capture_flashes, capture_send_code_requests, + check_location, get_form_action, get_session, is_authenticated, @@ -811,7 +812,7 @@ # Validate token - this should complete 2FA setup response = client.post("/tf-validate", data=dict(code=code), follow_redirects=True) assert b"You successfully changed" in response.data - assert response.history[0].location == "/tf-setup" + assert check_location(app, response.history[0].location, "/tf-setup") # Upon completion, session cookie shouldnt have any two factor stuff in it. session = get_session(response) @@ -1291,7 +1292,9 @@ # Test setup when re-authenticate required authenticate(client) response = client.get("tf-setup", follow_redirects=False) - assert "/verify?next=http://localhost/tf-setup" in response.location + assert check_location( + app, response.location, "/verify?next=http://localhost/tf-setup" + ) logout(client) # Now try again - follow redirects to get to verify form @@ -1318,7 +1321,8 @@ follow_redirects=False, ) assert response.status_code == 302 - assert response.location == "http://localhost/tf-setup" + assert check_location(app, response.location, "/tf-setup") + assert get_message("REAUTHENTICATION_SUCCESSFUL") == flashes[0]["message"].encode( "utf-8" ) @@ -1443,4 +1447,4 @@ # Validate token - this should complete 2FA setup response = client.post("/tf-validate", data=dict(code=code), follow_redirects=False) - assert response.location == "/post_setup_view" + assert check_location(app, response.location, "/post_setup_view") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Flask-Security-Too-5.3.2/tests/test_unified_signin.py new/Flask-Security-Too-5.3.3/tests/test_unified_signin.py --- old/Flask-Security-Too-5.3.2/tests/test_unified_signin.py 2023-10-24 04:21:35.000000000 +0200 +++ new/Flask-Security-Too-5.3.3/tests/test_unified_signin.py 2023-12-30 02:11:27.000000000 +0100 @@ -25,6 +25,7 @@ authenticate, capture_flashes, capture_reset_password_requests, + check_location, get_form_action, is_authenticated, logout, @@ -455,7 +456,7 @@ matcher = re.findall(r"\w+:.*", outbox[0].body, re.IGNORECASE) link = matcher[0].split(":", 1)[1] response = client.get(link, headers=headers, follow_redirects=False) - assert response.location == "/login" + assert check_location(app, response.location, "/login") # should be able to authenticate now. response = client.post( @@ -986,7 +987,9 @@ us_authenticate(client) response = client.get("us-setup", follow_redirects=False) verify_url = response.location - assert "/us-verify?next=http://localhost/us-setup" in verify_url + assert check_location( + app, response.location, "/us-verify?next=http://localhost/us-setup" + ) logout(client) us_authenticate(client) @@ -1017,7 +1020,7 @@ code = sms_sender.messages[0].split()[-1].strip(".") response = client.post(verify_url, data=dict(passcode=code), follow_redirects=False) - assert response.location == "http://localhost/us-setup" + assert check_location(app, response.location, "/us-setup") def test_verify_json(app, client, get_message): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Flask-Security-Too-5.3.2/tests/test_utils.py new/Flask-Security-Too-5.3.3/tests/test_utils.py --- old/Flask-Security-Too-5.3.2/tests/test_utils.py 2023-10-24 04:21:35.000000000 +0200 +++ new/Flask-Security-Too-5.3.3/tests/test_utils.py 2023-12-30 02:11:27.000000000 +0100 @@ -27,6 +27,7 @@ us_security_token_sent, ) from flask_security.utils import hash_data, hash_password +from flask_security.utils import config_value as cv from itsdangerous import BadSignature, SignatureExpired, URLSafeTimedSerializer from werkzeug.http import parse_cookie @@ -63,6 +64,16 @@ raise ValueError("Failed to figure out if authenticated") +def check_location(app, location, expected_base): + # verify response location. This can be absolute or relative based + # on configuration + redirect_validate_mode = cv("REDIRECT_VALIDATE_MODE", app=app) or [] + if "absolute" in redirect_validate_mode: + return location == f"http://localhost{expected_base}" + else: + return location == expected_base + + def verify_token(client_nc, token, status=None): # Use passed auth token in API that requires auth and verify status. # Pass in a client_nc to get valid results. ++++++ no-mongodb.patch ++++++ --- /var/tmp/diff_new_pack.hMEQuh/_old 2024-01-07 21:40:15.727931428 +0100 +++ /var/tmp/diff_new_pack.hMEQuh/_new 2024-01-07 21:40:15.731931573 +0100 @@ -1,8 +1,10 @@ -Index: Flask-Security-Too-5.1.1/tests/conftest.py -=================================================================== ---- Flask-Security-Too-5.1.1.orig/tests/conftest.py -+++ Flask-Security-Too-5.1.1/tests/conftest.py -@@ -879,7 +879,7 @@ def client_nc(request, sqlalchemy_app): +--- + tests/conftest.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/tests/conftest.py ++++ b/tests/conftest.py +@@ -891,7 +891,7 @@ def client_nc(request, sqlalchemy_app): return app.test_client(use_cookies=False) @@ -11,7 +13,7 @@ def clients(request, app, tmpdir, realdburl, realmongodburl): if request.param == "cl-sqlalchemy": ds = sqlalchemy_setup(request, app, tmpdir, realdburl) -@@ -925,7 +925,7 @@ def get_message_local(app): +@@ -937,7 +937,7 @@ def get_message_local(app): @pytest.fixture( ++++++ use-pyqrcodeng.patch ++++++ --- /var/tmp/diff_new_pack.hMEQuh/_old 2024-01-07 21:40:15.743932010 +0100 +++ /var/tmp/diff_new_pack.hMEQuh/_new 2024-01-07 21:40:15.747932155 +0100 @@ -1,8 +1,11 @@ -Index: Flask-Security-Too-5.1.1/flask_security/core.py -=================================================================== ---- Flask-Security-Too-5.1.1.orig/flask_security/core.py -+++ Flask-Security-Too-5.1.1/flask_security/core.py -@@ -1579,7 +1579,7 @@ class Security: +--- + flask_security/core.py | 2 +- + flask_security/totp.py | 10 +++------- + 2 files changed, 4 insertions(+), 8 deletions(-) + +--- a/flask_security/core.py ++++ b/flask_security/core.py +@@ -1607,7 +1607,7 @@ class Security: and "authenticator" in cv("TWO_FACTOR_ENABLED_METHODS", app=app) ) if need_qrcode: @@ -11,10 +14,8 @@ need_sms = ( cv("UNIFIED_SIGNIN", app=app) -Index: Flask-Security-Too-5.1.1/flask_security/totp.py -=================================================================== ---- Flask-Security-Too-5.1.1.orig/flask_security/totp.py -+++ Flask-Security-Too-5.1.1/flask_security/totp.py +--- a/flask_security/totp.py ++++ b/flask_security/totp.py @@ -140,15 +140,11 @@ class Totp: .. versionadded:: 4.0.0 """