Version in base suite: 20.0.0-2 Base version: zaqar_20.0.0-2 Target version: zaqar_20.0.0-2+deb13u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/z/zaqar/zaqar_20.0.0-2.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/z/zaqar/zaqar_20.0.0-2+deb13u1.dsc changelog | 16 + patches/CVE-2026-107363_OSSA-2026-043_Prohibit_arbitrary_project-id_for_websocket_protocol_access.patch | 120 ++++++++++ patches/CVE-2026-66139_OSSA-2026-029_Do_not_bypass_authentication_for_requests_with_EXTRA-SPEC_header.patch | 53 ++++ patches/CVE-2026-97404_OSSA-2026-042_Fix_authentication_bypass_by_empty_URL-Signature.patch | 34 ++ patches/series | 3 5 files changed, 226 insertions(+) dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmp_z0mqick/zaqar_20.0.0-2.dsc: no acceptable signature found dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmp_z0mqick/zaqar_20.0.0-2+deb13u1.dsc: no acceptable signature found diff -Nru zaqar-20.0.0/debian/changelog zaqar-20.0.0/debian/changelog --- zaqar-20.0.0/debian/changelog 2025-07-11 12:47:00.000000000 +0000 +++ zaqar-20.0.0/debian/changelog 2026-10-13 12:10:33.000000000 +0000 @@ -1,3 +1,19 @@ +zaqar (20.0.0-2+deb13u1) trixie; urgency=medium + + * CVE-2026-66139 / OSSA-2026-029: EXTRA-SPEC header bypasses Keystone + authentication. Applied upstream patch: "Do not bypass authentication for + requests with EXTRA-SPEC header". (Closes: #1142858). + * CVE-2026-97404 / OSSA-2026-042: Zaqar empty URL-Signature header + bypasses authentication. Applied upstream patch "Fix authentication + bypass by empty URL-Signature". (Closes: #1148897): + - CVE-2026-97404_OSSA-2026-042_Fix_authentication_bypass_by_empty_....patch + * CVE-2026-107363 / OSSA-2026-043: Zaqar WebSocket project substitution + allows cross-project queue access. Applied upstream patch "Prohibit + arbitrary project-id for websocket protocol access". (Closes: #1150261): + - CVE-2026-107363_OSSA-2026-043_Prohibit_arbitrary_project-id_fo....patch + + -- Thomas Goirand Tue, 13 Oct 2026 14:10:33 +0200 + zaqar (20.0.0-2) unstable; urgency=medium * Add export OS_OSLO_MESSAGING_RABBIT__PROCESSNAME to all daemons. diff -Nru zaqar-20.0.0/debian/patches/CVE-2026-107363_OSSA-2026-043_Prohibit_arbitrary_project-id_for_websocket_protocol_access.patch zaqar-20.0.0/debian/patches/CVE-2026-107363_OSSA-2026-043_Prohibit_arbitrary_project-id_for_websocket_protocol_access.patch --- zaqar-20.0.0/debian/patches/CVE-2026-107363_OSSA-2026-043_Prohibit_arbitrary_project-id_for_websocket_protocol_access.patch 1970-01-01 00:00:00.000000000 +0000 +++ zaqar-20.0.0/debian/patches/CVE-2026-107363_OSSA-2026-043_Prohibit_arbitrary_project-id_for_websocket_protocol_access.patch 2026-10-13 12:10:33.000000000 +0000 @@ -0,0 +1,120 @@ +Description: Prohibit arbitrary project-id for websocket protocol access +From: Takashi Kajinami +Date: Wed, 07 Oct 2026 02:10:12 +0900 +Bug: https://launchpad.net/bugs/2161402 +Bug-Debian: https://bugs.debian.org/1150261 +Change-Id: Id6055f9f6f115249a1321165ae93a91e69ea9dcc +Signed-off-by: Takashi Kajinami +Co-Authored-By: Hao Wang +Origin: https://review.opendev.org/c/zaqar/+/1009254 +Last-Update: 2026-10-07 + +diff --git a/releasenotes/notes/bug-2161402-f0b9d2052c12b958.yaml b/releasenotes/notes/bug-2161402-f0b9d2052c12b958.yaml +new file mode 100644 +index 0000000..e2e8188 +--- /dev/null ++++ b/releasenotes/notes/bug-2161402-f0b9d2052c12b958.yaml +@@ -0,0 +1,6 @@ ++--- ++security: ++ - | ++ `Bug 2161402 `_: Fixed ++ websocket protocol support allowing arbitrary cross project access for ++ any authenticated users. +diff --git a/zaqar/tests/unit/transport/websocket/v2/test_auth.py b/zaqar/tests/unit/transport/websocket/v2/test_auth.py +index beaeb00..ce0b615 100644 +--- a/zaqar/tests/unit/transport/websocket/v2/test_auth.py ++++ b/zaqar/tests/unit/transport/websocket/v2/test_auth.py +@@ -45,8 +45,12 @@ + auth_mock = mock.patch.object(auth_token.AuthProtocol, '__call__') + self.addCleanup(auth_mock.stop) + self.auth = auth_mock.start() +- self.env = {'keystone.token_info': { +- 'token': {'expires_at': '2035-08-05T15:16:33.603700+00:00'}}} ++ self.env = { ++ 'keystone.token_info': { ++ 'token': {'expires_at': '2035-08-05T15:16:33.603700+00:00'} ++ }, ++ 'X-PROJECT-ID': self.project_id, ++ } + + def test_post(self): + headers = self.headers.copy() +@@ -69,17 +73,41 @@ + self.assertEqual('200 OK', responses[0]) + + # Check that the env is available to future requests +- req = jsonutils.dumps({'action': consts.MESSAGE_LIST, +- 'body': {'queue_name': 'myqueue'}, +- 'headers': self.headers}) +- process_request = mock.patch.object(self.protocol._handler, +- 'process_request').start() ++ req = jsonutils.dumps({ ++ 'action': consts.MESSAGE_LIST, ++ 'body': {'queue_name': 'myqueue'}, ++ 'headers': self.headers ++ }) ++ process_request = mock.patch.object( ++ self.protocol._handler, 'process_request').start() + process_request.return_value = self.protocol._handler.create_response( + 200, {}) + self.protocol.onMessage(req, False) + self.assertEqual(1, process_request.call_count) + self.assertEqual(self.env, process_request.call_args[0][0]._env) + ++ def test_different_project(self): ++ headers = self.headers.copy() ++ headers['X-Auth-Token'] = 'mytoken1' ++ req = jsonutils.dumps({'action': 'authenticate', 'headers': headers}) ++ ++ msg_mock = mock.patch.object(self.protocol, 'sendMessage') ++ self.addCleanup(msg_mock.stop) ++ msg_mock = msg_mock.start() ++ self.protocol.onMessage(req, False) ++ ++ # Didn't send the response yet ++ self.assertEqual(0, msg_mock.call_count) ++ ++ headers = self.headers.copy() ++ headers['X-Project-ID'] = '7e55e1a7f' ++ req = test_utils.create_request(consts.QUEUE_LIST, {}, headers) ++ self.protocol.onMessage(req, False) ++ ++ self.assertEqual(1, msg_mock.call_count) ++ resp = jsonutils.loads(msg_mock.call_args[0][0]) ++ self.assertEqual(403, resp['headers']['status']) ++ + def test_post_between_auth(self): + headers = self.headers.copy() + headers['X-Auth-Token'] = 'mytoken1' +@@ -90,6 +118,9 @@ + msg_mock = msg_mock.start() + self.protocol.onMessage(req, False) + ++ # Didn't send the response yet ++ self.assertEqual(0, msg_mock.call_count) ++ + req = test_utils.create_request(consts.QUEUE_LIST, {}, self.headers) + self.protocol.onMessage(req, False) + +diff --git a/zaqar/transport/websocket/protocol.py b/zaqar/transport/websocket/protocol.py +index 8c19288..78598ad 100644 +--- a/zaqar/transport/websocket/protocol.py ++++ b/zaqar/transport/websocket/protocol.py +@@ -117,7 +117,16 @@ + elif payload.get('action') == 'authenticate': + return self._authenticate(payload, isBinary) + else: ++ if self._auth_strategy: ++ auth_project = self._auth_env.get("X-PROJECT-ID") ++ request_project = payload.get('headers', {}).get( ++ "X-Project-ID") ++ if not request_project or auth_project != request_project: ++ body = {'error': 'Not authenticated.'} ++ resp = self._handler.create_response(403, body, req) ++ return self._send_response(resp, isBinary) + resp = self._handler.process_request(req, self) ++ + if payload.get('action') == consts.SUBSCRIPTION_CREATE: + # NOTE(Eva-i): this will make further websocket + # notifications encoded in the same format as the last diff -Nru zaqar-20.0.0/debian/patches/CVE-2026-66139_OSSA-2026-029_Do_not_bypass_authentication_for_requests_with_EXTRA-SPEC_header.patch zaqar-20.0.0/debian/patches/CVE-2026-66139_OSSA-2026-029_Do_not_bypass_authentication_for_requests_with_EXTRA-SPEC_header.patch --- zaqar-20.0.0/debian/patches/CVE-2026-66139_OSSA-2026-029_Do_not_bypass_authentication_for_requests_with_EXTRA-SPEC_header.patch 1970-01-01 00:00:00.000000000 +0000 +++ zaqar-20.0.0/debian/patches/CVE-2026-66139_OSSA-2026-029_Do_not_bypass_authentication_for_requests_with_EXTRA-SPEC_header.patch 2026-10-13 12:10:33.000000000 +0000 @@ -0,0 +1,53 @@ +Author: Takashi Kajinami +Date: Wed, 22 Jul 2026 16:33:48 +0900 +Description: Do not bypass authentication for requests with EXTRA-SPEC header + Commit 9b6edcf6ca5aca45536fb6f5038068e506c9c673 introduced + the mechanism to pass down extra headers to drivers but this introduced + queue access with all authentication and athorization check enforced. + Remove the bypass to prohibit unauthenticated access. + . + Note that the "execute" interface has never been implemented actually + in drivers so this may have no user impact really. +Bug: https://launchpad.net/bugs/2161254 +Bug-Debian: https://bugs.debian.org/1142858 +Change-Id: Iab3a6c3d60d97c66c693964291ebc3cdb298c1b0 +Signed-off-by: Takashi Kajinami +Origin: upstream, https://review.opendev.org/c/openstack/zaqar/+/998411 +Last-Update: 2026-07-29 + +diff --git a/releasenotes/notes/bug-2161254-55c2748092268fb3.yaml b/releasenotes/notes/bug-2161254-55c2748092268fb3.yaml +new file mode 100644 +index 0000000..a36aeae +--- /dev/null ++++ b/releasenotes/notes/bug-2161254-55c2748092268fb3.yaml +@@ -0,0 +1,6 @@ ++--- ++security: ++ - | ++ `Bug 2161254 `_: Fixed ++ Requests with the ``EXTRA-SPEC`` header bypassed authentication and ++ policy check. +diff --git a/zaqar/transport/middleware/auth.py b/zaqar/transport/middleware/auth.py +index 6bc0444..1e5c53d 100644 +--- a/zaqar/transport/middleware/auth.py ++++ b/zaqar/transport/middleware/auth.py +@@ -32,16 +32,14 @@ + + def __call__(self, environ, start_response): + path = environ.get('PATH_INFO') +- extra_spec = environ.get('HTTP_EXTRA_SPEC') ++ signature = environ.get('HTTP_URL_SIGNATURE') ++ + # NOTE(flwang): The root path of Zaqar service shouldn't require any + # auth. + if path == '/': + return self._app(environ, start_response) + +- signature = environ.get('HTTP_URL_SIGNATURE') +- +- if (signature is None and extra_spec is None) or \ +- path.startswith('/v1'): ++ if signature is None or path.startswith('/v1'): + return self._auth_app(environ, start_response) + + return self._app(environ, start_response) diff -Nru zaqar-20.0.0/debian/patches/CVE-2026-97404_OSSA-2026-042_Fix_authentication_bypass_by_empty_URL-Signature.patch zaqar-20.0.0/debian/patches/CVE-2026-97404_OSSA-2026-042_Fix_authentication_bypass_by_empty_URL-Signature.patch --- zaqar-20.0.0/debian/patches/CVE-2026-97404_OSSA-2026-042_Fix_authentication_bypass_by_empty_URL-Signature.patch 1970-01-01 00:00:00.000000000 +0000 +++ zaqar-20.0.0/debian/patches/CVE-2026-97404_OSSA-2026-042_Fix_authentication_bypass_by_empty_URL-Signature.patch 2026-10-13 12:10:33.000000000 +0000 @@ -0,0 +1,34 @@ +From: Takashi Kajinami +Date: Thu, 24 Sep 2026 22:46:06 +0900 +Description: Fix authentication bypass by empty URL-Signature +Bug: https://launchpad.net/bugs/2164987 +Bug-Debian: https://bugs.debian.org/1148897 +Change-Id: Ib7aadf8d6de396ac9f0a11d6fcfa44849b194bf4 +Signed-off-by: Takashi Kajinami +Origin: https://review.opendev.org/c/openstack/zaqar/+/1007162 +Last-Update: 2026-09-24 + +diff --git a/releasenotes/notes/bug-2164987-c1138c80bdc41299.yaml b/releasenotes/notes/bug-2164987-c1138c80bdc41299.yaml +new file mode 100644 +index 0000000..addc084 +--- /dev/null ++++ b/releasenotes/notes/bug-2164987-c1138c80bdc41299.yaml +@@ -0,0 +1,5 @@ ++--- ++security: ++ - | ++ `Bug 2164987 `_ : Fixed ++ authentication bypass caused by an empty URL-Signature header. +diff --git a/zaqar/common/transport/wsgi/helpers.py b/zaqar/common/transport/wsgi/helpers.py +index a258e01..48c56fa 100644 +--- a/zaqar/common/transport/wsgi/helpers.py ++++ b/zaqar/common/transport/wsgi/helpers.py +@@ -40,7 +40,7 @@ + paths = headers.get('URL-PATHS', '').split(',') + signature = headers.get('URL-SIGNATURE') + +- if not signature: ++ if signature is None: + return + + if req.method not in methods: diff -Nru zaqar-20.0.0/debian/patches/series zaqar-20.0.0/debian/patches/series --- zaqar-20.0.0/debian/patches/series 2025-07-11 12:47:00.000000000 +0000 +++ zaqar-20.0.0/debian/patches/series 2026-10-13 12:10:33.000000000 +0000 @@ -1,3 +1,6 @@ #remove-trollius-from-requirements.txt.patch finished-fixing-upstream-tests.patch package-all-files.patch +CVE-2026-66139_OSSA-2026-029_Do_not_bypass_authentication_for_requests_with_EXTRA-SPEC_header.patch +CVE-2026-97404_OSSA-2026-042_Fix_authentication_bypass_by_empty_URL-Signature.patch +CVE-2026-107363_OSSA-2026-043_Prohibit_arbitrary_project-id_for_websocket_protocol_access.patch