Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-pybars3 for openSUSE:Factory
checked in at 2026-11-09 16:05:04
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pybars3 (Old)
and /work/SRC/openSUSE:Factory/.python-pybars3.new.3759290 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pybars3"
Mon Nov 9 16:05:04 2026 rev:4 rq:1396213 version:0.9.7
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pybars3/python-pybars3.changes
2025-06-04 20:29:22.791037382 +0200
+++
/work/SRC/openSUSE:Factory/.python-pybars3.new.3759290/python-pybars3.changes
2026-11-09 16:05:43.602536876 +0100
@@ -1,0 +2,6 @@
+Mon Nov 9 01:50:42 UTC 2026 - Steve Kowalik <[email protected]>
+
+- CVE-2026-119716: avoid code injection via bracketed paths (bsc#1289150)
+ * Add patch CVE-2026-119716.patch
+
+-------------------------------------------------------------------
New:
----
CVE-2026-119716.patch
----------(New B)----------
New:- CVE-2026-119716: avoid code injection via bracketed paths (bsc#1289150)
* Add patch CVE-2026-119716.patch
----------(New E)----------
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-pybars3.spec ++++++
--- /var/tmp/diff_new_pack.yjLY0e/_old 2026-11-09 16:05:44.734584335 +0100
+++ /var/tmp/diff_new_pack.yjLY0e/_new 2026-11-09 16:05:44.737584461 +0100
@@ -1,7 +1,7 @@
#
# spec file for package python-pybars3
#
-# Copyright (c) 2025 SUSE LLC
+# Copyright (c) 2026 SUSE LLC and contributors
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -22,9 +22,10 @@
Release: 0
Summary: Handlebarsjs templating for Python 3 and 2
License: LGPL-3.0-only
-Group: Development/Languages/Python
URL: https://github.com/wbond/%{base_name}
Source: https://github.com/wbond/%{base_name}/archive/%{version}.tar.gz
+# PATCH-FIX-OPENSUSE bsc#1289150 avoid code injection via bracketed paths
+Patch0: CVE-2026-119716.patch
BuildRequires: %{python_module PyMeta3 >= 0.5.1}
BuildRequires: %{python_module pip}
BuildRequires: %{python_module setuptools}
@@ -41,7 +42,7 @@
compatibility and numerous features from Handlebars.js 2.0.
%prep
-%setup -q -n pybars3-%{version}
+%autosetup -p1 -n pybars3-%{version}
%build
%pyproject_wheel
@@ -57,5 +58,5 @@
%license LICENSE
%doc readme.md changelog.md
%{python_sitelib}/pybars
-%{python_sitelib}/pybars3-%{version}*-info
+%{python_sitelib}/pybars3-%{version}.dist-info
++++++ CVE-2026-119716.patch ++++++
>From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Security Patch <[email protected]>
Date: Mon, 9 Nov 2026 12:43:00 +1100
Subject: [PATCH] Fix CVE-2026-119716: Escape bracketed path segments in
compiler
pybars/_compiler.py did not escape quotes, backslashes, or newlines inside
bracketed path segments (`notclosebracket`), allowing crafted templates to
break out of generated Python string literals in `resolve()` and
`resolve_subexpr()` and execute arbitrary Python code.
Escape `\n`, `\r`, `\`, `'`, and `"` in `notclosebracket`, and remove the
obsolete `.replace('.get("', '').replace('")', '')` in `find_lookup` so a
trailing `\"` followed by `)` cannot be stripped into a dangling backslash.
---
pybars/_compiler.py | 11 ++++++++---
tests/test_acceptance.py | 58 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 66 insertions(+), 3 deletions(-)
Index: pybars3-0.9.7/pybars/_compiler.py
===================================================================
--- pybars3-0.9.7.orig/pybars/_compiler.py
+++ pybars3-0.9.7/pybars/_compiler.py
@@ -111,7 +111,12 @@ notsquote ::= <escapedquote>
| (~("'") <anything>)
escapedquote ::= '\\' '"' => '\\"'
| "\\" "'" => "\\'"
-notclosebracket ::= (~(']') <anything>)
+notclosebracket ::= '\n' => '\\n'
+ | '\r' => '\\r'
+ | '\\' => '\\\\'
+ | '\'' => '\\\''
+ | '"' => '\\"'
+ | (~(']') <anything>)
safesymbol ::= ~<alt_inner> '['? (<letter>|'_'):start
(<letterOrDigit>|'_')+:symbol ']'? => start + u''.join(symbol)
symbol ::= ~<alt_inner> '['? (<letterOrDigit>|'-'|'@')+:symbol ']'? =>
u''.join(symbol)
partialname ::= <subexpression>:s => s
@@ -627,7 +632,7 @@ class CodeBuilder:
# TODO: compile this whole expression in the grammar; for now,
# fugly but only a compile time overhead.
# XXX: just rm.
- realname = path.replace('.get("', '').replace('")', '')
+ realname = path
self._result.grow([
u" value = helpers.get(u'%s')\n" % realname,
u" if value is None:\n"
Index: pybars3-0.9.7/tests/test_acceptance.py
===================================================================
--- pybars3-0.9.7.orig/tests/test_acceptance.py
+++ pybars3-0.9.7/tests/test_acceptance.py
@@ -2703,3 +2703,61 @@ class TestAcceptance(TestCase):
text = u"Hola {{name}}!"
context = {'name': u"Samira"}
self.assertRender(text, context, u"Hola Samira!")
+
+ def test_cve_2026_119716_bracketed_segment_code_injection(self):
+ executed = []
+
+ def side_effect():
+ executed.append(True)
+ return u"PWNED"
+
+ # 1. Simple bracketed path breakout attempt (single quotes)
+ tpl_simple = u"{{[a') or side_effect() or ('b]}}"
+ self.assertEqual(u"", render(tpl_simple, {'side_effect': side_effect}))
+
+ # 2. Complex dotted path breakout attempt
+ tpl_complex = u"{{foo.[a') or side_effect() or ('b]}}"
+ self.assertEqual(u"", render(tpl_complex, {'foo': {}, 'side_effect':
side_effect}))
+
+ # 3. Helper / block argument bracketed path breakout attempt
+ helpers = {'echo': lambda this, val: val or u""}
+ tpl_arg = u"{{echo [a') or __import__('os').system('echo pwned') or
('b]}}"
+ self.assertEqual(u"", render(tpl_arg, {}, helpers=helpers))
+
+ # 4. Subexpression helper name breakout attempt (double & single
quotes)
+ tpl_subexpr_dq = u'{{echo ([a", context) or
__import__("os").system("echo pwned") or ("b] 1)}}'
+ with self.assertRaises(PybarsError):
+ render(tpl_subexpr_dq, {}, helpers=helpers)
+
+ tpl_subexpr_sq = u"{{echo ([a', context) or
__import__('os').system('echo pwned') or ('b] 1)}}"
+ with self.assertRaises(PybarsError):
+ render(tpl_subexpr_sq, {}, helpers=helpers)
+
+ # 5. Secondary gadget via trailing `")` and backslash escaping
+ tpl_gadget = u'{{[a")]}}{{[\')]}}'
+ self.assertEqual(u"", render(tpl_gadget, {}))
+
+ # 6. Newline injection inside bracketed path segment
+ tpl_newline = u"{{[a'\n" + u" raise RuntimeError('injected')\n" +
u" ']}}"
+ self.assertEqual(u"", render(tpl_newline, {}))
+
+ self.assertEqual(executed, [])
+
+ def test_bracketed_segments_with_special_chars_resolve_correctly(self):
+ context = {
+ u"single'quote": u"val1",
+ u'double"quote': u"val2",
+ u"back\\slash": u"val3",
+ u'trailing")': u"val4",
+ u"nested": {
+ u"key'with\"quotes\\and\nnewline": u"val5"
+ }
+ }
+ self.assertEqual(u"val1", render(u"{{[single'quote]}}", context))
+ self.assertEqual(u"val2", render(u'{{[double"quote]}}', context))
+ self.assertEqual(u"val3", render(u"{{[back\\slash]}}", context))
+ self.assertEqual(u"val4", render(u'{{[trailing")]}}', context))
+ self.assertEqual(
+ u"val5",
+ render(u"{{nested.[key'with\"quotes\\and\nnewline]}}", context)
+ )