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

Hi,

Same as for Trixie, I'd like to address:
https://wiki.openstack.org/wiki/OSSN/OSSN-0097

[ Reason ]
Addressing OSSN-0097

[ Impact ]
Possible script injection in Horizon openrc served files.

[ Tests ]
Building the package runs upstream unit tests.

[ Risks ]
Small risk: patch is small and easy to understand. It just
blacklist $ and ! chars on top of what it previously did.

[ 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

[ Changes ]
Added upstream patch.

Please let me upload Horizon 3:23.0.0-5+deb12u2 to Bookworm p-u.

Cheers,

Thomas Goirand (zigo)
diff -Nru horizon-23.0.0/debian/changelog horizon-23.0.0/debian/changelog
--- horizon-23.0.0/debian/changelog     2023-09-05 11:31:00.000000000 +0200
+++ horizon-23.0.0/debian/changelog     2026-06-09 10:38:23.000000000 +0200
@@ -1,3 +1,11 @@
+horizon (3:23.0.0-5+deb12u2) bookworm; urgency=medium
+
+  * OSSN-0097: Horizon RC file generation does not escape special characters in
+    project. Applied upstream patch: "Escape $ character in shellfilter, and
+    use it consistently" (Closes: #1138845).
+
+ -- Thomas Goirand <[email protected]>  Tue, 09 Jun 2026 10:38:23 +0200
+
 horizon (3:23.0.0-5+deb12u1) bookworm; urgency=medium
 
   * CVE-2022-45582: Open redirect/phishing attack via "success_url" parameter,
diff -Nru 
horizon-23.0.0/debian/patches/OSSN-0097_Escape_dollar_character_in_shellfilter_and_use_it_consistently.patch
 
horizon-23.0.0/debian/patches/OSSN-0097_Escape_dollar_character_in_shellfilter_and_use_it_consistently.patch
--- 
horizon-23.0.0/debian/patches/OSSN-0097_Escape_dollar_character_in_shellfilter_and_use_it_consistently.patch
        1970-01-01 01:00:00.000000000 +0100
+++ 
horizon-23.0.0/debian/patches/OSSN-0097_Escape_dollar_character_in_shellfilter_and_use_it_consistently.patch
        2026-06-09 10:38:23.000000000 +0200
@@ -0,0 +1,111 @@
+From 933adb45c43ac5571f1f8d00526a673016f9b0a8 Mon Sep 17 00:00:00 2001
+From: Radomir Dopieralski <[email protected]>
+Date: Tue, 12 May 2026 19:18:50 +0200
+Subject: [PATCH] Escape $ character in shellfilter, and use it consistently
+
+Make sure the special characters included in user-provided values
+don't break the shell scripts generated by Horizon.
+
+Fixes-bug: 2152240
+
+Change-Id: Iec01e820a7ff0d4d3bed7f8929cb9c3229deb502
+Signed-off-by: Radomir Dopieralski <[email protected]>
+---
+
+Index: horizon/horizon/templatetags/shellfilter.py
+===================================================================
+--- horizon.orig/horizon/templatetags/shellfilter.py
++++ horizon/horizon/templatetags/shellfilter.py
+@@ -23,6 +23,8 @@ def shellfilter(value):
+     """Replace HTML chars for shell usage."""
+     replacements = {'\\': '\\\\',
+                     '`': '\\`',
++                    '$': '\\$',
++                    '!': '\\!',
+                     "'": "\\'",
+                     '"': '\\"'}
+     for search, repl in replacements.items():
+Index: 
horizon/openstack_dashboard/dashboards/identity/application_credentials/templates/application_credentials/openrc.sh.template
+===================================================================
+--- 
horizon.orig/openstack_dashboard/dashboards/identity/application_credentials/templates/application_credentials/openrc.sh.template
++++ 
horizon/openstack_dashboard/dashboards/identity/application_credentials/templates/application_credentials/openrc.sh.template
+@@ -1,9 +1,9 @@
+ {% load shellfilter %}#!/usr/bin/env bash
+ 
+ export OS_AUTH_TYPE=v3applicationcredential
+-export OS_AUTH_URL={{ auth_url }}
++export OS_AUTH_URL="{{ auth_url|shellfilter }}"
+ export OS_IDENTITY_API_VERSION=3
+ export OS_REGION_NAME="{{ region|shellfilter }}"
+-export OS_INTERFACE={{ interface }}
+-export OS_APPLICATION_CREDENTIAL_ID={{ application_credential_id }}
+-export OS_APPLICATION_CREDENTIAL_SECRET={{ application_credential_secret }}
++export OS_INTERFACE="{{ interface|shellfilter }}"
++export OS_APPLICATION_CREDENTIAL_ID="{{ application_credential_id|shellfilter 
}}"
++export OS_APPLICATION_CREDENTIAL_SECRET="{{ 
application_credential_secret|shellfilter }}"
+Index: 
horizon/openstack_dashboard/dashboards/project/api_access/templates/api_access/openrc.sh.template
+===================================================================
+--- 
horizon.orig/openstack_dashboard/dashboards/project/api_access/templates/api_access/openrc.sh.template
++++ 
horizon/openstack_dashboard/dashboards/project/api_access/templates/api_access/openrc.sh.template
+@@ -11,11 +11,11 @@
+ # OpenStack API is version 3. For example, your cloud provider may implement
+ # Image API v1.1, Block Storage API v2, and Compute API v2.0. OS_AUTH_URL is
+ # only for the Identity API served through keystone.
+-export OS_AUTH_URL={{ auth_url }}
++export OS_AUTH_URL="{{ auth_url|shellfilter }}"
+ 
+ # With the addition of Keystone we have standardized on the term **project**
+ # as the entity that owns the resources.
+-export OS_PROJECT_ID={{ tenant_id }}
++export OS_PROJECT_ID="{{ tenant_id|shellfilter }}"
+ export OS_PROJECT_NAME="{{ tenant_name|shellfilter }}"
+ export OS_USER_DOMAIN_NAME="{{ user_domain_name|shellfilter }}"
+ if [ -z "$OS_USER_DOMAIN_NAME" ]; then unset OS_USER_DOMAIN_NAME; fi
+@@ -33,7 +33,7 @@ export OS_USERNAME="{{ user.username|she
+ # With Keystone you pass the keystone password.
+ echo "Please enter your OpenStack Password for project $OS_PROJECT_NAME as 
user $OS_USERNAME: "
+ read -sr OS_PASSWORD_INPUT
+-export OS_PASSWORD=$OS_PASSWORD_INPUT
++export OS_PASSWORD="$OS_PASSWORD_INPUT"
+ 
+ # If your configuration has multiple regions, we set that information here.
+ # OS_REGION_NAME is optional and only valid in certain environments.
+@@ -41,5 +41,5 @@ export OS_REGION_NAME="{{ region|shellfi
+ # Don't leave a blank variable, unset it if it was empty
+ if [ -z "$OS_REGION_NAME" ]; then unset OS_REGION_NAME; fi
+ 
+-export OS_INTERFACE={{ interface }}
+-export OS_IDENTITY_API_VERSION={{ os_identity_api_version }}
++export OS_INTERFACE="{{ interface|shellfilter }}"
++export OS_IDENTITY_API_VERSION="{{ os_identity_api_version|shellfilter }}"
+Index: horizon/openstack_dashboard/dashboards/project/api_access/tests.py
+===================================================================
+--- horizon.orig/openstack_dashboard/dashboards/project/api_access/tests.py
++++ horizon/openstack_dashboard/dashboards/project/api_access/tests.py
+@@ -55,7 +55,7 @@ class APIAccessTests(test.TestCase):
+         openrc = 'project/api_access/openrc.sh.template'
+         self.assertTemplateUsed(res, openrc)
+         name = 'export OS_USERNAME="{}"'.format(self.request.user.username)
+-        p_id = 'export OS_PROJECT_ID={}'.format(self.request.user.tenant_id)
++        p_id = 'export OS_PROJECT_ID="{}"'.format(self.request.user.tenant_id)
+         domain = 'export OS_USER_DOMAIN_NAME="{}"'.format(
+             self.request.user.user_domain_name)
+         self.assertIn(name.encode('utf-8'), res.content)
+@@ -215,7 +215,7 @@ class TemplateRenderTest(test.TestCase):
+             context,
+             template.Context(context))
+ 
+-        self.assertIn("OS_REGION_NAME=\"Colorado\"", out)
++        self.assertIn('OS_REGION_NAME="Colorado"', out)
+ 
+     def test_openrc_region_not_set(self):
+         context = {
+@@ -228,7 +228,7 @@ class TemplateRenderTest(test.TestCase):
+             context,
+             template.Context(context))
+ 
+-        self.assertIn("OS_REGION_NAME=\"\"", out)
++        self.assertIn('OS_REGION_NAME=""', out)
+ 
+     def test_clouds_yaml_set_region(self):
+         context = {
diff -Nru horizon-23.0.0/debian/patches/series 
horizon-23.0.0/debian/patches/series
--- horizon-23.0.0/debian/patches/series        2023-09-05 11:31:00.000000000 
+0200
+++ horizon-23.0.0/debian/patches/series        2026-06-09 10:38:23.000000000 
+0200
@@ -7,3 +7,4 @@
 Make-site_branding-tag-work-with-Django-4.0.patch
 remove-test_rbac_panels.patch
 CVE-2022-45582_Fix_success_url_parameter_issue_for_Edit_Snapshot.patch
+OSSN-0097_Escape_dollar_character_in_shellfilter_and_use_it_consistently.patch

Reply via email to