Debian Patches

Status for mistral/23.0.0-2

Patch Description Author Forwarded Bugs Origin Last update
CVE-2026-93860_Restrict_the_maintenance_endpoint_to_admins.patch Restrict the maintenance endpoint to admins The root-level /maintenance resource read and changed Mistral's cluster
maintenance state with no policy enforcement: the controller cleared
the request context and called the service/DB layer directly. Switching
the status to PAUSED is a cluster-wide operation that pauses running
executions across every project, and reading the status exposes
cluster-wide operational state, yet any authenticated token holder
could reach both methods.
.
Add 'maintenance:get' and 'maintenance:update' policies (both default
rule:admin_only) and enforce them in MaintenanceController.get() and
put() before the request context is cleared, so only administrators can
read or change the maintenance status. Operators can relax the rules in
policy.yaml if needed.
.

diff --git a/mistral/api/controllers/maintenance.py b/mistral/api/controllers/maintenance.py
index c24ef014..60a5fc05 100644
Arnaud Morin <arnaud.morin@gmail.com> yes debian upstream upstream, pre-OSSA mailing list 2026-10-01
install-missing-files.patch Install missing files Thomas Goirand <zigo@debian.org> not-needed 2018-02-25
Load_defaults_from_oslo.concurrency.patch Load defaults from oslo.concurrency Under my env (ie: Debian packages), I've seen mistral-api trying to
write under:
.
/var/lock/nova/oslo_read_shm_<HOSTNAME>_mistral-api
.
Why /var/lock/nova is a mistery, but I want to fix this.
.
This patch:
.
Ensures oslo.concurrency lockutils uses the value from the parsed config.
oslo.concurrency registers its opts on import, so the option exists;
call set_defaults *after* CONF(...) so we pick up any value from files.
.
Sets the lockutils default to the configured path so external locks
(synchronized(external=True)) use the right directory.

===================================================================
Thomas Goirand <zigo@debian.org> no 2025-10-03
CVE-2026-97147_Fix_create-or-update_of_definitions_hijacking_other_projects_rows.patch Fix create-or-update of definitions hijacking other projects' rows When several projects have a workflow or ad-hoc action definition with
the same name, create_or_update_workflow_definition() and
create_or_update_action_definition() looked the existing object up with
an unordered first() over a query that isn't scoped to a single project
(admin requests see all projects). The lookup could therefore return
another project's definition, and since project_id is always rewritten
to the current project on write (see
model_base.register_secure_model_hooks), updating that object moved it
into the caller's project. If the caller's project already had its own
definition with that name, the move violated the (name, namespace,
project_id) unique constraint and the resulting DBDuplicateEntry was
raised at commit time, surfacing as an HTTP 500.
.
This intermittently broke the python-mistralclient functional job:
the tests leaked 'wb.ac1' action definitions in two projects, after
which every 'workbook-create' of a definition containing actions failed
with a 500, depending on which project's row the DB returned first.
.
Look the existing definition up by the full unique key (name, namespace
and project id of the current security context), which is the only row
a subsequent write may collide with. Definitions of other projects are
no longer touched, and the update targets the definition by id so the
inner lookup is unambiguous.
.

diff --git a/mistral/db/v2/sqlalchemy/api.py b/mistral/db/v2/sqlalchemy/api.py
index 6fa439be..0836d5a3 100644
Arnaud Morin <arnaud.morin@gmail.com> yes debian upstream upstream, pre-OSSA mailing list 2026-10-01
CVE-2026-97147_Enforce_access_control_when_updating_action_definitions.patch Enforce access control when updating action definitions update_action_definition() resolved the target by name with a query
that, for a non-admin caller, also matches public definitions of other
projects (the secure query includes scope=='public'). It then rewrote
project_id to the caller on write, so a non-admin could modify and
effectively steal another project's public ad-hoc action, and it had no
guard against modifying a system action at the DB layer -- unlike
update_workflow_definition(), which calls check_db_obj_access().
.
Look the definition up in the caller's own project first so that, when
several projects share a name, the caller's own object is updated, and
call check_db_obj_access() to reject cross-project and system-action
modifications by non-admins. The check is skipped when there is no
authentication context, since 'mistral-db-manage populate' re-registers
preinstalled ad-hoc actions through this path without one.
.

diff --git a/mistral/db/v2/sqlalchemy/api.py b/mistral/db/v2/sqlalchemy/api.py
index 0836d5a3..087643d4 100644
Arnaud Morin <arnaud.morin@gmail.com> yes debian upstream upstream, pre-OSSA mailing list 2026-10-01
CVE-2026-97147_Enforce_access_control_when_updating_workbooks_and_environments.patch Enforce access control when updating workbooks and environments update_workbook() and update_environment()/create_or_update_environment()
resolved the target with a query that returns public resources of other
projects, and wrote to it without an ownership check. A non-admin project
member could therefore modify (and, since the update sends scope, unpublish)
another project's public workbook or environment.
.
Resolve the object within the caller's own project first and call
check_db_obj_access() before writing, consistently with workflow and action
definitions. The check is skipped when there is no authentication context.
.
update_workbook() was previously protected only transitively: a workbook
update cascades into update_workflow_definition(), which is guarded, so the
whole transaction rolled back. Making the workflow/action lookup
project-scoped (previous change) removes that incidental protection, so the
guard is now applied to the workbook row itself.
.

diff --git a/mistral/db/v2/sqlalchemy/api.py b/mistral/db/v2/sqlalchemy/api.py
index 087643d4..ad060b4b 100644
Arnaud Morin <arnaud.morin@gmail.com> yes debian upstream upstream, pre-OSSA mailing list 2026-10-01
CVE-2026-97147_Resolve_own-project_object_when_updating_code_sources_dynamic_actions.patch Resolve own-project object when updating code sources / dynamic actions update_code_source() and update_dynamic_action_definition() resolved the
target with a lookup that can return an object of another project (admins
get an insecure cross-project lookup, and public objects are visible to any
caller), then rewrote project_id to the caller on write. When several
projects have an object with the same name, this could clobber or move the
wrong one.
.
Resolve the object within the caller's own project first and apply
check_db_obj_access(), consistently with workflow/action/workbook/environment
updates. These resources are admin-only by default policy, so this is
hardening / data integrity rather than a cross-tenant escalation.
.

diff --git a/mistral/db/v2/sqlalchemy/api.py b/mistral/db/v2/sqlalchemy/api.py
index ad060b4b..fd536e34 100644
Arnaud Morin <arnaud.morin@gmail.com> yes debian upstream upstream, pre-OSSA mailing list 2026-10-01
CVE-2026-97147_Resolve_own-project_object_Fix-test-DB-cleanup-for-code-sources-and-dynamic-actions.patch Clean up code sources and dynamic actions in test DB cleanup DbTestCase._clean_db() never deleted code_sources and
dynamic_action_definitions rows, so those two tables were not reset
between tests. With the serial test run used by pkgos-dh_auto_test,
rows left behind by the CVE-2026-97147 DB tests (a public code source
"cs1" and dynamic actions referencing class names that do not exist
in its content) leaked into later tests in the same process: listing
actions built descriptors for them and failed with 500 "module 'cs1'
has no attribute 'UpdatedClass'".
.
Delete both tables in _clean_db() for each of the two contexts it
already iterates, dynamic action definitions before code sources to
respect the foreign key order.

===================================================================
Thomas Goirand <zigo@debian.org> no debian 2026-10-01
CVE-2026-97147_Resolve_own-project_cron_trigger_in_create_or_update_cron_trigger.patch Resolve own-project cron trigger in create_or_update_cron_trigger create_or_update_cron_trigger() looked the existing trigger up with a
cross-project-capable query (public triggers are visible to any caller,
admins get an insecure lookup), so it could update another project's trigger
and move it into the caller's project. Resolve it within the caller's own
project first, consistently with the other resources.
.
update_cron_trigger() is deliberately left unchanged: it is called by the
periodic scheduler to update next-execution bookkeeping of triggers across
all projects, and the cron trigger REST API exposes no update operation.

diff --git a/mistral/db/v2/sqlalchemy/api.py b/mistral/db/v2/sqlalchemy/api.py
index fd536e34..f6225ae9 100644
Arnaud Morin <arnaud.morin@gmail.com> yes debian upstream upstream, pre-OSSA mailing list 2026-10-01
CVE-2026-93861_Only_allow_the_owner_of_a_resource_to_share_it.patch Only allow the owner of a resource to share it Sharing a workflow (POST /v2/workflows/<id>/members) only verified that
the caller could fetch the workflow definition and that its scope was
private. The secure query that fetches the definition also returns
resources shared with the caller through an accepted membership, so a
project that a workflow was shared with - once it accepted the share -
could re-share the owner's private workflow with an arbitrary third
project.
.
The resulting ResourceMember row is stamped with the re-sharing
project's id (the caller), not the owner's, so:
.
* the real owner can neither list nor delete that membership;
* the third project can accept it and thereby read and execute the
owner's private workflow, which the owner never shared with it;
* only the re-sharing project, not the owner, can revoke it.
.
Reject the share unless the caller is the owner of the resource
(wf_db.project_id == security.get_project_id()), with a 403. This does
not affect the previously reported "pending" case, where the member
cannot see the workflow yet and the fetch already fails with 404.
.

diff --git a/mistral/api/controllers/v2/member.py b/mistral/api/controllers/v2/member.py
index 7dc0c805..1e22e7ba 100644
Arnaud Morin <arnaud.morin@gmail.com> yes debian upstream upstream, pre-OSSA mailing list 2026-10-01
CVE-2026-93858_Fix_RCE_via_std.ssh_proxied_proxy_command.patch Fix RCE via std.ssh_proxied proxy_command The std.ssh_proxied action passed a caller-supplied proxy_command
straight to paramiko.ProxyCommand in execute_command_via_gateway.
paramiko.ProxyCommand runs the string as a local subprocess on the
executor host from its constructor - before any SSH authentication and
independently of the SSH credentials, gateway or target supplied (a bad
or empty key does not stop it). std.ssh_proxied is a built-in action, so
any authenticated, project-scoped user could run arbitrary commands on
every Mistral executor by submitting it through the action-execution
API. This is a remote code execution vulnerability.
.
Gate proxy_command behind a new '[action_std_ssh] allowed_proxy_commands'
allow-list (empty by default). execute_command_via_gateway now rejects,
with an ActionException, any proxy_command whose exact value is not
listed, before paramiko is invoked - so by default proxy_command is
disabled and no local subprocess can be spawned. Operators who rely on
it must add the exact command string to the option. The rejection reason
reaches the caller thanks to the preceding change.
.

===================================================================
Arnaud Morin <arnaud.morin@gmail.com> yes debian upstream upstream, pre-OSSA mailing list 2026-10-01

All known versions for source package 'mistral'

Links