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
          """

Reply via email to