On 9/4/26 12:55 PM, Adam D. Barratt wrote:
Control: tags -1 + confirmed
On Thu, 2026-08-20 at 14:20 +0200, Thomas Goirand wrote:
I'd like to upload a new version of Zaqar to address:
https://security.openstack.org/ossa/OSSA-2026-029.html
aka:
https://bugs.debian.org/1142858
Please go ahead.
Regards,
Adam
Hi Adam,
I integrated this change to the previous ones (re-indented here, so it
wraps at 74 cols, for readability):
* 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_authe....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_....patch
New debdiff is attached. Package has been uploaded. Please approve it.
Cheers,
Thomas Goirand (zigo)
diff -Nru zaqar-20.0.0/debian/changelog zaqar-20.0.0/debian/changelog
--- zaqar-20.0.0/debian/changelog 2025-07-11 14:47:00.000000000 +0200
+++ zaqar-20.0.0/debian/changelog 2026-10-13 14:10:33.000000000 +0200
@@ -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 <[email protected]> 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 01:00:00.000000000 +0100
+++
zaqar-20.0.0/debian/patches/CVE-2026-107363_OSSA-2026-043_Prohibit_arbitrary_project-id_for_websocket_protocol_access.patch
2026-10-13 14:10:33.000000000 +0200
@@ -0,0 +1,120 @@
+Description: Prohibit arbitrary project-id for websocket protocol access
+From: Takashi Kajinami <[email protected]>
+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 <[email protected]>
+Co-Authored-By: Hao Wang <[email protected]>
+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 <https://bugs.launchpad.net/zaqar/+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 01:00:00.000000000 +0100
+++
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 14:10:33.000000000 +0200
@@ -0,0 +1,53 @@
+Author: Takashi Kajinami <[email protected]>
+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 <[email protected]>
+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 <https://bugs.launchpad.net/zaqar/+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 01:00:00.000000000 +0100
+++
zaqar-20.0.0/debian/patches/CVE-2026-97404_OSSA-2026-042_Fix_authentication_bypass_by_empty_URL-Signature.patch
2026-10-13 14:10:33.000000000 +0200
@@ -0,0 +1,34 @@
+From: Takashi Kajinami <[email protected]>
+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 <[email protected]>
+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 <https://bugs.launchpad.net/zaqar/+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 14:47:00.000000000 +0200
+++ zaqar-20.0.0/debian/patches/series 2026-10-13 14:10:33.000000000 +0200
@@ -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