Your message dated Sat, 11 Jul 2026 10:32:49 +0000
with message-id <[email protected]>
and subject line Released in 13.6
has caused the Debian Bug report #1139646,
regarding trixie-pu: package vitrage/14.0.0-4 (CVE-2026-28370)
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact [email protected]
immediately.)


-- 
1139646: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1139646
Debian Bug Tracking System
Contact [email protected] with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: trixie
X-Debbugs-Cc: [email protected]
Control: affects -1 + src:vitrage
User: [email protected]
Usertags: pu

Hi,

[ Reason ]
I'd like to address CVE-2026-28370, and the security team said it would be
through p-u with no DSA.

[ Impact ]
CVE-2026-28370: Remote code execution through Vitrage query parser

[ Tests ]
Vitrage build process includes unit tests from upstream.

[ Risks ]
Not much, the patch is rather small, and upstream CI has functional tests.

[ 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 ]
Just upstream patch.

Please allow me to upload Vitrage 14.0.0-4+deb13u1 to Trixie p-u.

Cheers,

Thomas Goirand (zigo)
diff -Nru vitrage-14.0.0/debian/changelog vitrage-14.0.0/debian/changelog
--- vitrage-14.0.0/debian/changelog     2025-07-11 14:28:56.000000000 +0200
+++ vitrage-14.0.0/debian/changelog     2026-06-09 09:48:17.000000000 +0200
@@ -1,3 +1,11 @@
+vitrage (14.0.0-4+deb13u1) trixie; urgency=medium
+
+  * CVE-2026-28370 / OSSA-2026-003: Remote code execution through Vitrage query
+    parser. Applied upstream patch "Replace eval with function matching".
+    (Closes: #1139452)
+
+ -- Thomas Goirand <[email protected]>  Tue, 09 Jun 2026 09:48:17 +0200
+
 vitrage (14.0.0-4) unstable; urgency=medium
 
   * Add export OS_OSLO_MESSAGING_RABBIT__PROCESSNAME for all daemons.
diff -Nru 
vitrage-14.0.0/debian/patches/CVE-2026-28370_OSSA-2026-003_Replace_eval_with_function_matching.patch
 
vitrage-14.0.0/debian/patches/CVE-2026-28370_OSSA-2026-003_Replace_eval_with_function_matching.patch
--- 
vitrage-14.0.0/debian/patches/CVE-2026-28370_OSSA-2026-003_Replace_eval_with_function_matching.patch
        1970-01-01 01:00:00.000000000 +0100
+++ 
vitrage-14.0.0/debian/patches/CVE-2026-28370_OSSA-2026-003_Replace_eval_with_function_matching.patch
        2026-06-09 09:48:17.000000000 +0200
@@ -0,0 +1,147 @@
+Author: Dmitriy Rabotyagov <[email protected]>
+Date: Tue, 30 Sep 2025 20:46:39 +0200
+Description: Replace eval with function matching
+ Using eval in code is not safe and may lead to security
+ risks, especially given that query itself is supplied by a user.
+ .
+ This refactors the code making is presumably safe
+ and prone to code injections, which are possible with eval.
+Story: 2011539
+Task: 52866
+Bug-Debian: https://bugs.debian.org/1139452
+Change-Id: If629023052aa2c067c419bba10837f77bcc3e59c
+Signed-off-by: Dmitriy Rabotyagov <[email protected]>
+Origin: https://review.opendev.org/c/openstack/vitrage/+/962646
+Last-Update: 2026-06-09
+
+diff --git a/releasenotes/notes/grap_query_eval_fixup-9232ce40ad85993e.yaml 
b/releasenotes/notes/grap_query_eval_fixup-9232ce40ad85993e.yaml
+new file mode 100644
+index 0000000..9fa203a
+--- /dev/null
++++ b/releasenotes/notes/grap_query_eval_fixup-9232ce40ad85993e.yaml
+@@ -0,0 +1,5 @@
++---
++security:
++  - |
++    A security issue in the entity graph querying mechanism has been fixed.
++    This change hardens the query parser against malicious input.
+diff --git a/vitrage/graph/query.py b/vitrage/graph/query.py
+index c206a4c..c11cb46 100644
+--- a/vitrage/graph/query.py
++++ b/vitrage/graph/query.py
+@@ -12,6 +12,7 @@
+ # License for the specific language governing permissions and limitations
+ # under the License.
+ 
++import operator
+ from oslo_log import log as logging
+ 
+ from vitrage.common.exception import VitrageError
+@@ -21,13 +22,21 @@
+ operators = [
+     '<',
+     '<=',
+-    # '=',
+     '==',
+     '!=',
+     '>=',
+     '>',
+ ]
+ 
++ops = {
++    '<': operator.lt,
++    '<=': operator.le,
++    '==': operator.eq,
++    '!=': operator.ne,
++    '>=': operator.ge,
++    '>': operator.gt,
++}
++
+ logical_operations = [
+     'and',
+     'or'
+@@ -64,10 +73,7 @@
+     :return: a predicate "match(item)"
+     """
+     try:
+-        expression = _create_query_expression(query=query_dict)
+-        LOG.debug('create_predicate::%s', expression)
+-        expression = 'lambda item: ' + expression
+-        return eval(expression)
++        return _create_query_function(query=query_dict)
+     except Exception as e:
+         LOG.error('invalid query format %s. Exception: %s',
+                   query_dict, e)
+@@ -75,46 +81,42 @@
+                            query_dict, e)
+ 
+ 
+-def _create_query_expression(query, parent_operator=None):
+-    expressions = []
++def _create_query_function(query, parent_operator=None):
+ 
+     # First element or element under logical operation
+     if not parent_operator and isinstance(query, dict):
+         (key, value) = query.copy().popitem()
+-        return _create_query_expression(value, key)
++        return _create_query_function(value, key)
+ 
+     # Continue recursion on logical (and/or) operation
+     elif parent_operator in logical_operations and isinstance(query, list):
+-        for val in query:
+-            expressions.append(_create_query_expression(val))
+-        return _join_logical_operator(parent_operator, expressions)
++        predicates = [_create_query_function(val) for val in query]
++
++        if not predicates:
++            return lambda item: False
++
++        if parent_operator == 'and':
++            return lambda item: all(p(item) for p in predicates)
++        elif parent_operator == 'or':
++            return lambda item: any(p(item) for p in predicates)
+ 
+     # Recursion evaluate leaf (stop condition)
+     elif parent_operator in operators:
+-        for key, val in query.items():
+-            expressions.append('item.get(' + _evaluable_str(key) + ')' +
+-                               parent_operator + ' ' + _evaluable_str(val))
+-        return _join_logical_operator('and', expressions)
++        predicates = []
++        op_func = ops[parent_operator]
++        for field, value in query.items():
++            predicates.append(
++                lambda item, f=field, v=value: op_func(item.get(f), v)
++            )
++
++        # Multiple conditions under a comparison operator are implicitly 'and'
++        if len(predicates) > 1:
++            return lambda item: all(p(item) for p in predicates)
++        elif predicates:
++            return predicates[0]
++        else:
++            return lambda item: False
++
+     else:
+         raise VitrageError('invalid partial query format',
+                            parent_operator, query)
+-
+-
+-def _evaluable_str(value):
+-    """wrap string/unicode with back tick"""
+-    if isinstance(value, str):
+-        return '\'' + value + '\''
+-    else:
+-        return str(value)
+-
+-
+-def _join_logical_operator(op, expressions):
+-    """Create an expressions string
+-
+-    Example input:
+-        op='AND'
+-        expressions=['a == b', 'c < d']
+-    Example output: (a == b AND c < d)
+-    """
+-    separator = ' ' + op + ' '
+-    return '(' + separator.join(expressions) + ')'
diff -Nru vitrage-14.0.0/debian/patches/series 
vitrage-14.0.0/debian/patches/series
--- vitrage-14.0.0/debian/patches/series        2025-07-11 14:28:56.000000000 
+0200
+++ vitrage-14.0.0/debian/patches/series        2026-06-09 09:48:17.000000000 
+0200
@@ -2,3 +2,4 @@
 fix-oslo-config-generator.patch
 reproducible-build.patch
 remove-pysnmp-lextudio-from-requirements.patch
+CVE-2026-28370_OSSA-2026-003_Replace_eval_with_function_matching.patch

--- End Message ---
--- Begin Message ---
Version: 13.6

This update was released as part of 13.6.

--- End Message ---

Reply via email to