1
0

6 Commits

Author SHA256 Message Date
2b003d55b5 Accepting request 1328049 from Cloud:OpenStack:Factory
- add
  0001-Fix-privilege-escalation-via-spoofed-identity-header.patch:
  (bsc#1256800, CVE-2026-22797)

OBS-URL: https://build.opensuse.org/request/show/1328049
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/python-keystonemiddleware?expand=0&rev=21
2026-01-19 17:38:34 +00:00
70caa19773 - add
0001-Fix-privilege-escalation-via-spoofed-identity-header.patch:
  (bsc#1256800, CVE-2026-22797)

OBS-URL: https://build.opensuse.org/package/show/Cloud:OpenStack:Factory/python-keystonemiddleware?expand=0&rev=61
2026-01-19 09:22:22 +00:00
9e6228b85f Accepting request 1316920 from Cloud:OpenStack:Factory
- add conflicts/obsoletes

- update to 10.12.0:
  * Remove Python 3.9 support
  * Revert "Switch from python-memcache to pymemcache"
  * Revert "Strip inet(6) prefix"
  * Add TLS support to MemcacheClientPool
  * add pyproject.toml to support pip 23.1
  * Strip inet(6) prefix
  * Apply upper constraints to build documentation
  * Update master for stable/2025.1
  * Switch from python-memcache to pymemcache
  * Imported Translations from Zanata
- switch to singlespec

- update to 10.9.0:
  * Fix memcached dependencies's doc bug
  * Imported Translations from Zanata
  * Remove Python 3.8 support
  * Use oslo.utils to escape IPv6 address
  * Get rid of pkg\_resources
  * Replace deprecated constant\_time\_compare
  * Bump hacking (slightly)
  * Update master for stable/2024.2
  * s3token: Fix usage of removed Identity v2 API
  * Imported Translations from Zanata

- Initial package

OBS-URL: https://build.opensuse.org/request/show/1316920
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/python-keystonemiddleware?expand=0&rev=20
2025-11-10 18:18:26 +00:00
7be10705ec - add conflicts/obsoletes
OBS-URL: https://build.opensuse.org/package/show/Cloud:OpenStack:Factory/python-keystonemiddleware?expand=0&rev=59
2025-11-10 13:14:05 +00:00
57c1fb1dcb - update to 10.12.0:
* Remove Python 3.9 support
  * Revert "Switch from python-memcache to pymemcache"
  * Revert "Strip inet(6) prefix"
  * Add TLS support to MemcacheClientPool
  * add pyproject.toml to support pip 23.1
  * Strip inet(6) prefix
  * Apply upper constraints to build documentation
  * Update master for stable/2025.1
  * Switch from python-memcache to pymemcache
  * Imported Translations from Zanata
- switch to singlespec

OBS-URL: https://build.opensuse.org/package/show/Cloud:OpenStack:Factory/python-keystonemiddleware?expand=0&rev=58
2025-11-09 18:31:15 +00:00
a4571cb916 - update to 10.9.0:
* Fix memcached dependencies's doc bug
  * Imported Translations from Zanata
  * Remove Python 3.8 support
  * Use oslo.utils to escape IPv6 address
  * Get rid of pkg\_resources
  * Replace deprecated constant\_time\_compare
  * Bump hacking (slightly)
  * Update master for stable/2024.2
  * s3token: Fix usage of removed Identity v2 API
  * Imported Translations from Zanata
- Initial package

OBS-URL: https://build.opensuse.org/package/show/Cloud:OpenStack:Factory/python-keystonemiddleware?expand=0&rev=57
2025-07-01 22:49:17 +00:00
6 changed files with 251 additions and 75 deletions

View File

@@ -0,0 +1,147 @@
From e15e33fe9bbd4faa361ab7eb1950fb75ca93c7de Mon Sep 17 00:00:00 2001
From: Grzegorz Grasza <xek@redhat.com>
Date: Thu, 8 Jan 2026 14:46:19 +0100
Subject: [PATCH] Fix privilege escalation via spoofed identity headers
The external_oauth2_token middleware did not sanitize incoming
authentication headers before processing OAuth 2.0 tokens. This
allowed an attacker to send forged identity headers (e.g.,
X-Is-Admin-Project, X-Roles, X-User-Id) that would not be cleared
by the middleware, potentially enabling privilege escalation.
This fix adds a call to remove_auth_headers() at the start of
request processing to sanitize all incoming identity headers,
matching the secure behavior of the main auth_token middleware.
Closes-Bug: #2129018
Change-Id: Idd4fe1d17a25b3064b31f454d9830242f345e018
Signed-off-by: Jeremy Stanley <fungi@yuggoth.org>
Signed-off-by: Artem Goncharov <artem.goncharov@gmail.com>
---
keystonemiddleware/external_oauth2_token.py | 7 +-
.../test_external_oauth2_token_middleware.py | 76 +++++++++++++++++++
2 files changed, 81 insertions(+), 2 deletions(-)
diff --git a/keystonemiddleware/external_oauth2_token.py b/keystonemiddleware/external_oauth2_token.py
index c02cace..32fd4e4 100644
--- a/keystonemiddleware/external_oauth2_token.py
+++ b/keystonemiddleware/external_oauth2_token.py
@@ -33,6 +33,7 @@ from keystoneauth1.loading import session as session_loading
from keystonemiddleware._common import config
from keystonemiddleware.auth_token import _cache
+from keystonemiddleware.auth_token import _request
from keystonemiddleware.exceptions import ConfigurationError
from keystonemiddleware.exceptions import KeystoneMiddlewareException
from keystonemiddleware.i18n import _
@@ -534,7 +535,7 @@ class ExternalAuth2Protocol(object):
**cache_kwargs)
return _cache.TokenCache(self._log, **cache_kwargs)
- @webob.dec.wsgify()
+ @webob.dec.wsgify(RequestClass=_request._AuthTokenRequest)
def __call__(self, req):
"""Handle incoming request."""
self.process_request(req)
@@ -545,8 +546,10 @@ class ExternalAuth2Protocol(object):
"""Process request.
:param request: Incoming request
- :type request: _request.AuthTokenRequest
+ :type request: _request._AuthTokenRequest
"""
+ request.remove_auth_headers()
+
access_token = None
if (request.authorization and
request.authorization.authtype == 'Bearer'):
diff --git a/keystonemiddleware/tests/unit/test_external_oauth2_token_middleware.py b/keystonemiddleware/tests/unit/test_external_oauth2_token_middleware.py
index d23fedb..3d69a47 100644
--- a/keystonemiddleware/tests/unit/test_external_oauth2_token_middleware.py
+++ b/keystonemiddleware/tests/unit/test_external_oauth2_token_middleware.py
@@ -1823,6 +1823,82 @@ class ExternalOauth2TokenMiddlewareClientSecretBasicTest(
self.assertEqual(resp.headers.get('WWW-Authenticate'),
'Authorization OAuth 2.0 uri="%s"' % self._audience)
+ def test_spoofed_headers_are_sanitized(self):
+ """Test that spoofed identity headers are removed and replaced.
+
+ This test verifies the fix for a privilege escalation vulnerability
+ where an attacker could send spoofed identity headers that would not
+ be cleared by the middleware, allowing unauthorized access.
+ """
+ conf = copy.deepcopy(self._test_conf)
+ self.set_middleware(conf=conf)
+
+ # Use non-admin roles in the token metadata
+ non_admin_roles = 'member,reader'
+ non_admin_metadata = copy.deepcopy(self._default_metadata)
+ non_admin_metadata['roles'] = non_admin_roles
+
+ def mock_resp(request, context):
+ return self._introspect_response(
+ request, context,
+ auth_method=self._auth_method,
+ introspect_client_id=self._test_client_id,
+ introspect_client_secret=self._test_client_secret,
+ access_token=self._token,
+ active=True,
+ metadata=non_admin_metadata
+ )
+
+ self.requests_mock.post(self._introspect_endpoint,
+ json=mock_resp)
+ self.requests_mock.get(self._auth_url,
+ json=VERSION_LIST_v3,
+ status_code=300)
+
+ # Attempt to spoof multiple identity headers
+ spoofed_headers = get_authorization_header(self._token)
+ spoofed_headers.update({
+ 'X-Identity-Status': 'Confirmed',
+ 'X-Is-Admin-Project': 'true',
+ 'X-User-Id': 'spoofed_admin_user_id',
+ 'X-User-Name': 'spoofed_admin',
+ 'X-Roles': 'admin,superuser',
+ 'X-Project-Id': 'spoofed_project_id',
+ 'X-User-Domain-Id': 'spoofed_domain_id',
+ 'X-User-Domain-Name': 'spoofed_domain',
+ })
+
+ resp = self.call_middleware(
+ headers=spoofed_headers,
+ expected_status=200,
+ method='GET', path='/vnfpkgm/v1/vnf_packages',
+ environ={'wsgi.input': FakeWsgiInput(FakeSocket(None))}
+ )
+ self.assertEqual(FakeApp.SUCCESS, resp.body)
+
+ # Verify spoofed headers were replaced with actual token values
+ env = resp.request.environ
+
+ # X-Is-Admin-Project should not be present (not the spoofed 'true')
+ # because the token has non-admin roles and the middleware only sets
+ # this header when is_admin is true
+ self.assertNotIn('HTTP_X_IS_ADMIN_PROJECT', env)
+
+ # User info should match the token, not the spoofed values
+ self.assertEqual(self._user_id, env['HTTP_X_USER_ID'])
+ self.assertEqual(self._user_name, env['HTTP_X_USER_NAME'])
+ self.assertEqual(self._user_domain_id, env['HTTP_X_USER_DOMAIN_ID'])
+ self.assertEqual(
+ self._user_domain_name,
+ env['HTTP_X_USER_DOMAIN_NAME']
+ )
+
+ # Roles should be from the token, not spoofed
+ self.assertEqual(non_admin_roles, env['HTTP_X_ROLES'])
+
+ # Project info should match the token
+ self.assertEqual(self._project_id, env['HTTP_X_PROJECT_ID'])
+
class ExternalAuth2ProtocolTest(BaseExternalOauth2TokenMiddlewareTest):
--
2.52.0

View File

@@ -1,12 +0,0 @@
<services>
<service mode="manual" name="renderspec">
<param name="input-template">https://opendev.org/openstack/rpm-packaging/raw/master/openstack/keystonemiddleware/keystonemiddleware.spec.j2</param>
<param name="output-name">python-keystonemiddleware.spec</param>
<param name="requirements">https://opendev.org/openstack/keystonemiddleware/raw/master/requirements.txt</param>
<param name="changelog-email">cloud-devel@suse.de</param>
<param name="changelog-provider">gh,openstack,keystonemiddleware</param>
</service>
<service mode="manual" name="download_files">
</service>
<service name="format_spec_file" mode="manual"/>
</services>

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:0da92b4af5178410e15a1b99f56d9cdeb2546eed088c69bc39e666fe09f869bf
size 215566

View File

@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2d14c9a6eb48a0c5e81f0661cbeea974a209b20579e6daaf917d88b792f6cf38
size 212213

View File

@@ -1,3 +1,46 @@
-------------------------------------------------------------------
Mon Jan 19 09:21:51 UTC 2026 - Dirk Müller <dmueller@suse.com>
- add
0001-Fix-privilege-escalation-via-spoofed-identity-header.patch:
(bsc#1256800, CVE-2026-22797)
-------------------------------------------------------------------
Mon Nov 10 13:13:55 UTC 2025 - Dirk Müller <dmueller@suse.com>
- add conflicts/obsoletes
-------------------------------------------------------------------
Sun Nov 9 18:30:58 UTC 2025 - Dirk Müller <dmueller@suse.com>
- update to 10.12.0:
* Remove Python 3.9 support
* Revert "Switch from python-memcache to pymemcache"
* Revert "Strip inet(6) prefix"
* Add TLS support to MemcacheClientPool
* add pyproject.toml to support pip 23.1
* Strip inet(6) prefix
* Apply upper constraints to build documentation
* Update master for stable/2025.1
* Switch from python-memcache to pymemcache
* Imported Translations from Zanata
- switch to singlespec
-------------------------------------------------------------------
Tue Jul 1 22:35:56 UTC 2025 - Dirk Müller <dmueller@suse.com>
- update to 10.9.0:
* Fix memcached dependencies's doc bug
* Imported Translations from Zanata
* Remove Python 3.8 support
* Use oslo.utils to escape IPv6 address
* Get rid of pkg\_resources
* Replace deprecated constant\_time\_compare
* Bump hacking (slightly)
* Update master for stable/2024.2
* s3token: Fix usage of removed Identity v2 API
* Imported Translations from Zanata
-------------------------------------------------------------------
Tue Sep 3 13:06:47 UTC 2024 - cloud-devel@suse.de
@@ -737,5 +780,5 @@ Wed Sep 10 11:55:45 UTC 2014 - dmueller@suse.com
-------------------------------------------------------------------
Mon Jul 21 07:36:58 UTC 2014 - dmueller@suse.com
- Initial package
- Initial package

View File

@@ -1,7 +1,7 @@
#
# spec file for package python-keystonemiddleware
#
# Copyright (c) 2024 SUSE LLC
# Copyright (c) 2026 SUSE LLC and contributors
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -17,37 +17,61 @@
Name: python-keystonemiddleware
Version: 10.7.1
Version: 10.12.0
Release: 0
Summary: Middleware for OpenStack Identity
License: Apache-2.0
Group: Development/Languages/Python
URL: https://docs.openstack.org/keystonemiddleware
Source0: https://files.pythonhosted.org/packages/source/k/keystonemiddleware/keystonemiddleware-10.7.1.tar.gz
Source0: https://files.pythonhosted.org/packages/source/k/keystonemiddleware/keystonemiddleware-%{version}.tar.gz
# PATCH-FIX-UPSTREAM
Patch1: 0001-Fix-privilege-escalation-via-spoofed-identity-header.patch
BuildRequires: %{python_module WebOb >= 1.7.1}
BuildRequires: %{python_module WebTest}
BuildRequires: %{python_module cryptography}
BuildRequires: %{python_module fixtures}
BuildRequires: %{python_module keystoneauth1 >= 3.12.0}
BuildRequires: %{python_module keystoneclient >= 3.20.0}
BuildRequires: %{python_module oslo.cache >= 1.26.0}
BuildRequires: %{python_module oslo.config >= 5.2.0}
BuildRequires: %{python_module oslo.context >= 2.19.2}
BuildRequires: %{python_module oslo.i18n >= 3.15.3}
BuildRequires: %{python_module oslo.messaging}
BuildRequires: %{python_module oslo.serialization >= 2.18.0}
BuildRequires: %{python_module oslo.utils >= 3.33.0}
BuildRequires: %{python_module oslotest}
BuildRequires: %{python_module pip}
BuildRequires: %{python_module pycadf >= 1.1.0}
BuildRequires: %{python_module python-memcached}
BuildRequires: %{python_module requests >= 2.14.2}
BuildRequires: %{python_module requests-mock}
BuildRequires: %{python_module stestr}
BuildRequires: %{python_module stevedore}
BuildRequires: %{python_module testresources}
BuildRequires: %{python_module testtools}
BuildRequires: %{python_module wheel}
BuildRequires: openstack-macros
BuildRequires: python3-WebOb >= 1.7.1
BuildRequires: python3-WebTest
BuildRequires: python3-cryptography
BuildRequires: python3-fixtures
BuildRequires: python3-keystoneauth1 >= 3.12.0
BuildRequires: python3-keystoneclient >= 3.20.0
BuildRequires: python3-oslo.cache >= 1.26.0
BuildRequires: python3-oslo.config >= 5.2.0
BuildRequires: python3-oslo.context >= 2.19.2
BuildRequires: python3-oslo.i18n >= 3.15.3
BuildRequires: python3-oslo.messaging
BuildRequires: python3-oslo.serialization >= 2.18.0
BuildRequires: python3-oslo.utils >= 3.33.0
BuildRequires: python3-oslotest
BuildRequires: python3-pycadf >= 1.1.0
BuildRequires: python3-python-memcached
BuildRequires: python3-requests >= 2.14.2
BuildRequires: python3-requests-mock
BuildRequires: python3-stestr
BuildRequires: python3-stevedore
BuildRequires: python3-testresources
BuildRequires: python3-testtools
Requires: python-WebOb >= 1.7.1
Requires: python-keystoneauth1 >= 3.12.0
Requires: python-keystoneclient >= 3.20.0
Requires: python-oslo.cache >= 1.26.0
Requires: python-oslo.config >= 5.2.0
Requires: python-oslo.context >= 2.19.2
Requires: python-oslo.i18n >= 3.15.3
Requires: python-oslo.log >= 3.36.0
Requires: python-oslo.messaging
Requires: python-oslo.serialization >= 2.18.0
Requires: python-oslo.utils >= 3.33.0
Requires: python-pycadf >= 1.1.0
Requires: python-python-memcached
Requires: python-requests >= 2.14.2
BuildArch: noarch
%if "python%{python_nodots_ver}" == "%{primary_python}"
Obsoletes: python3-keystonemiddleware < %{version}
%else
Conflicts: python3-keystonemiddleware < %{version}
%endif
%python_subpackages
%description
This package contains middleware modules designed to provide authentication
@@ -55,31 +79,6 @@ and authorization features to web services other than Keystone
The most prominent module is keystonemiddleware.auth_token. This package
does not expose any CLI or Python API features.
%package -n python3-keystonemiddleware
Summary: Middleware for OpenStack Identity
Requires: python3-WebOb >= 1.7.1
Requires: python3-keystoneauth1 >= 3.12.0
Requires: python3-keystoneclient >= 3.20.0
Requires: python3-oslo.cache >= 1.26.0
Requires: python3-oslo.config >= 5.2.0
Requires: python3-oslo.context >= 2.19.2
Requires: python3-oslo.i18n >= 3.15.3
Requires: python3-oslo.log >= 3.36.0
Requires: python3-oslo.messaging
Requires: python3-oslo.serialization >= 2.18.0
Requires: python3-oslo.utils >= 3.33.0
Requires: python3-pycadf >= 1.1.0
Requires: python3-python-memcached
Requires: python3-requests >= 2.14.2
%description -n python3-keystonemiddleware
This package contains middleware modules designed to provide authentication
and authorization features to web services other than Keystone
The most prominent module is keystonemiddleware.auth_token. This package
does not expose any CLI or Python API features.
This package contains the Python 3.x module
%package -n python-keystonemiddleware-doc
Summary: Documentation for Middleware for OpenStack Identity
BuildRequires: python3-Sphinx
@@ -91,18 +90,17 @@ BuildRequires: python3-sphinxcontrib-svg2pdfconverter
Documentation for Middleware for OpenStack Identity.
%prep
%autosetup -p1 -n keystonemiddleware-10.7.1
%py_req_cleanup
%autosetup -p1 -n keystonemiddleware-%{version}
%build
%{py3_build}
%pyproject_wheel
%install
%{py3_install}
%pyproject_install
# generate html docs
export PYTHONPATH=.
PBR_VERSION=%{version} %sphinx_build -b html doc/source doc/build/html
sphinx-build -b html doc/source doc/build/html
# remove the sphinx-build leftovers
rm -rf doc/build/html/.{doctrees,buildinfo}
@@ -110,11 +108,11 @@ rm -rf doc/build/html/.{doctrees,buildinfo}
rm -v keystonemiddleware/tests/unit/audit/test_logging_notifier.py
%{openstack_stestr_run}
%files -n python3-keystonemiddleware
%files %{python_files}
%license LICENSE
%doc ChangeLog README.rst
%{python3_sitelib}/keystonemiddleware
%{python3_sitelib}/*.egg-info
%doc README.rst
%{python_sitelib}/keystonemiddleware
%{python_sitelib}/keystonemiddleware-%{version}.dist-info
%files -n python-keystonemiddleware-doc
%doc doc/build/html