forked from pool/python-keystonemiddleware
Compare commits
50 Commits
| Author | SHA256 | Date | |
|---|---|---|---|
| 2b003d55b5 | |||
| 70caa19773 | |||
| 9e6228b85f | |||
| 7be10705ec | |||
| 57c1fb1dcb | |||
| a4571cb916 | |||
| ac2ebc7947 | |||
| 5258d49a6f | |||
| a6c69cabc2 | |||
| ab18a0ca3a | |||
| 2ee2d97858 | |||
| 5ff60647ed | |||
| ec5bd65676 | |||
| 53a1c78fdd | |||
| decf8e1da9 | |||
| b37fa22a85 | |||
| 6529f113b9 | |||
| 4c369f1450 | |||
| 8e336d8ec1 | |||
| 5cc523fe35 | |||
| 3f79a02e14 | |||
| 61f65dd337 | |||
| ba1628a5a0 | |||
| a5dfd45be3 | |||
| af2f346c55 | |||
| 82b39bc10c | |||
| a16d2a980e | |||
| 5a3ff10b45 | |||
| 285fbb00e5 | |||
| 21a94f5e42 | |||
| 59a954877c | |||
| d175c0d2a3 | |||
| a75266e6cb | |||
| ebd79c3dba | |||
| f786ffbaff | |||
| 293fa1f4b5 | |||
| e1a2414e55 | |||
| 2af2915e69 | |||
| e7410f0f5c | |||
| 91572965cf | |||
| 8a11cf9c9a | |||
| f2bcba5054 | |||
| 7f87dfe7a0 | |||
| 2f7a568cb9 | |||
| 6468cf9708 | |||
| b1f140461c | |||
| 2b29269946 | |||
| c2f6779b60 | |||
| 6ea61311e1 | |||
|
|
b8da896088 |
147
0001-Fix-privilege-escalation-via-spoofed-identity-header.patch
Normal file
147
0001-Fix-privilege-escalation-via-spoofed-identity-header.patch
Normal 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
|
||||
|
||||
12
_service
12
_service
@@ -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>
|
||||
3
keystonemiddleware-10.12.0.tar.gz
Normal file
3
keystonemiddleware-10.12.0.tar.gz
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0da92b4af5178410e15a1b99f56d9cdeb2546eed088c69bc39e666fe09f869bf
|
||||
size 215566
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e5bb479f81b2b2a8b3d367e4a6b76383ffaf58a80184a0c612dc847308de1a74
|
||||
size 211964
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:2d14c9a6eb48a0c5e81f0661cbeea974a209b20579e6daaf917d88b792f6cf38
|
||||
size 212213
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user