Package: release.debian.org
Severity: normal
Tags: trixie
X-Debbugs-Cc: [email protected]
Control: affects -1 + src:aodh
User: [email protected]
Usertags: pu

Hi,

I have uploaded aodh 20.0.0-2+deb13u2 to Trixie p-u.
Here's why:

[ Reason ]
I'd like to get the fix for this upstream bug, reported in
upstream bug tracker (ie: launchpad, which is the BTS for
OpenStack):
https://bugs.launchpad.net/aodh/+bug/2167496

Basically, someone repeating the project_id parameter can
fool the AODH API and bypass auth.

[ Impact ]
What's written above.

[ Tests ]
My patch (which I forwarded upstream and was merged) includes
new test for this issue. We've pushed the new version in
production, and saw no regression.

[ Risks ]
Low risk because of what's just above.

[ Checklist ]
  [x] *all* changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in (old)stable
  [x] the issue is verified as fixed in unstable

Please approve aodh/aodh_20.0.0-2+deb13u2 into
Trixie p-u for the next point release.

Cheers,

Thomas Goirand (zigo)
diff -Nru aodh-20.0.0/debian/changelog aodh-20.0.0/debian/changelog
--- aodh-20.0.0/debian/changelog        2026-08-12 09:57:24.000000000 +0200
+++ aodh-20.0.0/debian/changelog        2026-11-05 12:40:16.000000000 +0100
@@ -1,3 +1,15 @@
+aodh (20.0.0-2+deb13u2) trixie; urgency=high
+
+  * lp-2167496: Fix an authorization bypass in the alarm listing API where
+    duplicated project_id query filters could bypass project scope:
+    authorization validated the first filter value while the storage query
+    kept the last one, letting a non-admin user list another project's
+    alarms, including action URLs. Applied upstream patch: "Duplicated
+    query fields are now rejected with a 400 response" (Closes: #1153094):
+    - lp-2167496_Fix_duplicate_project_id_query_filter_bypass_project....patch
+
+ -- Thomas Goirand <[email protected]>  Thu, 05 Nov 2026 12:40:16 +0100
+
 aodh (20.0.0-2+deb13u1) trixie; urgency=medium
 
   * CVE-2026-76878 / OSSA-2026-036: Aodh does not correctly enforce project
diff -Nru 
aodh-20.0.0/debian/patches/lp-2167496_Fix_duplicate_project_id_query_filter_bypass_project_scope.patch
 
aodh-20.0.0/debian/patches/lp-2167496_Fix_duplicate_project_id_query_filter_bypass_project_scope.patch
--- 
aodh-20.0.0/debian/patches/lp-2167496_Fix_duplicate_project_id_query_filter_bypass_project_scope.patch
      1970-01-01 01:00:00.000000000 +0100
+++ 
aodh-20.0.0/debian/patches/lp-2167496_Fix_duplicate_project_id_query_filter_bypass_project_scope.patch
      2026-11-05 12:40:16.000000000 +0100
@@ -0,0 +1,106 @@
+Description: Fix duplicate project_id query filter bypassing project scope
+ The alarm listing API validated the first occurrence of the project_id
+ query filter while building the storage filter dict from all query
+ objects, keeping the last one. A non-admin caller could pass their own
+ project_id first and a foreign project_id second, passing authorization
+ while the storage lookup ran against the foreign project, disclosing
+ that project's alarm definitions including secret-bearing action URLs.
+ Duplicated query fields are now rejected with a 400 response, so the
+ authorization check and the storage filter always operate on the same
+ value.
+Author: Thomas Goirand <[email protected]>
+Date: Wed, 28 Oct 2026 10:42:03 +0100
+Forwarded: 
https://opendev.org/openstack/aodh/commit/7381d2cd6ef922fb6aed912e7366268176d42b06
+Bug: https://launchpad.net/bugs/2167496
+Bug-Debian: https://bugs.debian.org/1153094
+Assisted-By: Infomaniak Euria-Code
+Last-Update: 2026-11-05
+
+Index: aodh/aodh/api/controllers/v2/alarms.py
+===================================================================
+--- aodh.orig/aodh/api/controllers/v2/alarms.py
++++ aodh/aodh/api/controllers/v2/alarms.py
+@@ -886,6 +886,15 @@ class AlarmsController(rest.RestControll
+                 'op', ops,
+                 'only operations %s are allowed' % ALARM_QUERY_OPS_ALLOWED
+             )
++        # Only one query per field is allowed: a duplicated field could
++        # make the authorization check below operate on the first value
++        # while the storage filter built at the end keeps the last one,
++        # which would bypass the project scope.
++        if len(q) != len(keys):
++            raise wsme.exc.InvalidInput(
++                'field', keys,
++                'duplicate query fields are not allowed'
++            )
+ 
+         if ('all_projects' in keys and
+                 v2_utils.get_query_value(q, 'all_projects', 'boolean')):
+Index: aodh/aodh/tests/functional/api/v2/test_alarm_scenarios.py
+===================================================================
+--- aodh.orig/aodh/tests/functional/api/v2/test_alarm_scenarios.py
++++ aodh/aodh/tests/functional/api/v2/test_alarm_scenarios.py
+@@ -249,6 +249,48 @@ class TestAlarms(TestAlarmsBase):
+         )
+         self.assertEqual(0, len(alarms))
+ 
++    def _create_other_project_alarm(self):
++        alarm = copy.deepcopy(default_alarms(self.auth_headers)[0])
++        alarm.alarm_id = 'd'
++        alarm.name = 'other-project-alarm'
++        alarm.user_id = 'other-user'
++        alarm.project_id = 'other-project'
++        self.alarm_conn.create_alarm(alarm)
++
++    def test_get_alarm_duplicate_project_id_own_project_first(self):
++        self._create_other_project_alarm()
++        project = self.auth_headers['X-Project-Id']
++        q = [{'field': 'project_id', 'op': 'eq', 'value': project},
++             {'field': 'project_id', 'op': 'eq', 'value': 'other-project'}]
++        response = self.get_json(
++            '/alarms',
++            headers=self.auth_headers,
++            q=q,
++            expect_errors=True,
++            status=400
++        )
++        self.assertEqual(400, response.status_code)
++        faultstring = 'duplicate query fields are not allowed'
++        self.assertIn(faultstring,
++                      response.json['error_message']['faultstring'])
++
++    def test_get_alarm_duplicate_project_id_other_project_first(self):
++        self._create_other_project_alarm()
++        project = self.auth_headers['X-Project-Id']
++        q = [{'field': 'project_id', 'op': 'eq', 'value': 'other-project'},
++             {'field': 'project_id', 'op': 'eq', 'value': project}]
++        response = self.get_json(
++            '/alarms',
++            headers=self.auth_headers,
++            q=q,
++            expect_errors=True,
++            status=400
++        )
++        self.assertEqual(400, response.status_code)
++        faultstring = 'duplicate query fields are not allowed'
++        self.assertIn(faultstring,
++                      response.json['error_message']['faultstring'])
++
+     def test_get_alarm_forbiden(self):
+         pf = os.path.abspath('aodh/tests/functional/api/v2/policy.yaml-test')
+         self.CONF.set_override('policy_file', pf, group='oslo_policy')
+Index: 
aodh/releasenotes/notes/fix-duplicate-project-id-query-filter-scope-f6b935de6318.yaml
+===================================================================
+--- /dev/null
++++ 
aodh/releasenotes/notes/fix-duplicate-project-id-query-filter-scope-f6b935de6318.yaml
+@@ -0,0 +1,10 @@
++---
++security:
++  - |
++    `Bug #2167496 <https://bugs.launchpad.net/aodh/+bug/2167496>`_:
++    Fixed an authorization bypass in the alarm listing API where repeated
++    ``project_id`` query filters made the authorization check operate on
++    the first value while the storage query filtered on the last one,
++    allowing a non-admin user to list another project's alarms, including
++    their action URLs. Repeated query fields are now rejected with
++    ``HTTP 400``.
diff -Nru aodh-20.0.0/debian/patches/series aodh-20.0.0/debian/patches/series
--- aodh-20.0.0/debian/patches/series   2026-08-12 09:57:24.000000000 +0200
+++ aodh-20.0.0/debian/patches/series   2026-11-05 12:40:16.000000000 +0100
@@ -3,3 +3,4 @@
 remove-httpdomain-sphinx-ext.patch
 add-a-healthcheck_disable-file.patch
 CVE-2026-76878-aodh-lp-2161276-2025.1.patch
+lp-2167496_Fix_duplicate_project_id_query_filter_bypass_project_scope.patch

Reply via email to