Command injection in convert_shape_compare
Description
PaddlePaddle before 2.6.0 has a command injection in convert_shape_compare. This resulted in the ability to execute arbitrary commands on the operating system.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
PaddlePaddle before 2.6.0 contains a command injection vulnerability in convert_shape_compare, allowing arbitrary OS command execution.
Vulnerability
Description
CVE-2023-52314 is a command injection vulnerability in PaddlePaddle's convert_shape_compare function, affecting versions prior to 2.6.0. The function improperly handles user-supplied input, allowing an attacker to inject operating system commands [3]. The root cause is insufficient sanitization of arguments passed to convert_shape_compare, which can lead to arbitrary command execution [2].
Exploitation
An attacker can exploit this vulnerability by providing crafted input to convert_shape_compare, typically through a PaddlePaddle model or API that accepts user-controlled strings. No authentication is required if the vulnerable endpoint is exposed, and the attacker only needs network access to the service [3]. The attack complexity is low, as the injection is straightforward once the function is reachable.
Impact
Successful exploitation allows an attacker to execute arbitrary commands on the underlying operating system with the privileges of the PaddlePaddle process. This can lead to full system compromise, data theft, or further lateral movement within the network [1].
Mitigation
PaddlePaddle has fixed this vulnerability in version 2.6.0 [2]. Users should upgrade to the latest version immediately. As of January 2024, no workarounds are documented; upgrading is the only recommended mitigation [3].
AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
PaddlePaddlePyPI | < 2.6.0 | 2.6.0 |
Affected products
2- PaddlePaddle/PaddlePaddlev5Range: 0
Patches
15ed9478fdef9[Dy2St]Fix BUG with Potential security vulnerabilities (#60097)
3 files changed · +0 −194
python/paddle/jit/dy2static/convert_operators.py+0 −71 modified@@ -693,77 +693,6 @@ def has_negative(list_shape): return x.shape -def convert_shape_compare(left, *args): - """ - A function handles comparison difference between Paddle and Python. - For example, if x and y are Tensors, x.shape == y.shape will return single - boolean Value (True/False). However, paddle.shape(x) == paddle.shape(y) is - an element-wise comparison. The difference can cause dy2stat error. So we - create this function to handle the difference. - - Args: - left: variable - *args: compare_op(str), variable, compare_op(str), variable, where - compare_op means "<", ">", "==", "!=", etc. - Returns: - If the variables to compare are NOT Paddle Variables, we will return as - Python like "a op1 b and b op2 c and ... ". - If the variables to compare are Paddle Variables, we will do elementwise - comparsion first and then reduce to a boolean whose numel is 1. - - """ - args_len = len(args) - assert ( - args_len >= 2 - ), "convert_shape_compare needs at least one right compare variable" - assert ( - args_len % 2 == 0 - ), "Illegal input for convert_shape_compare, *args should be op(str), var, op(str), var ..." - num_cmp = args_len // 2 - if isinstance(left, (Variable, Value)): - - def reduce_compare(x, op_str, y): - element_wise_result = eval("x " + op_str + " y") - if op_str == "!=": - return paddle.any(element_wise_result) - elif ( - op_str == "is" - or op_str == "is not" - or op_str == "in" - or op_str == "not in" - ): - return element_wise_result - else: - return paddle.all(element_wise_result) - - final_result = reduce_compare(left, args[0], args[1]) - for i in range(1, num_cmp): - cmp_left = args[i * 2 - 1] - cmp_op = args[i * 2] - cmp_right = args[i * 2 + 1] - cur_result = reduce_compare(cmp_left, cmp_op, cmp_right) - final_result = convert_logical_and( - lambda: final_result, lambda: cur_result - ) - return final_result - else: - cmp_left = left - final_result = None - for i in range(num_cmp): - cmp_op = args[i * 2] - cmp_right = args[i * 2 + 1] - cur_result = eval("cmp_left " + cmp_op + " cmp_right") - if final_result is None: - final_result = cur_result - else: - final_result = final_result and cur_result - - if final_result is False: - return False - cmp_left = cmp_right - return final_result - - def cast_bool_if_necessary(var): assert isinstance(var, (Variable, Value)) if convert_dtype(var.dtype) not in ['bool']:
python/paddle/jit/dy2static/__init__.py+0 −1 modified@@ -26,7 +26,6 @@ convert_logical_or as Or, convert_pop as Pop, convert_shape as Shape, - convert_shape_compare, convert_var_dtype as AsDtype, convert_while_loop as While, indexable as Indexable,
test/dygraph_to_static/test_convert_operators.py+0 −122 modified@@ -71,128 +71,6 @@ def callable_list(x, y): self.assertEqual(paddle.jit.to_static(callable_list)(1, 2), 3) -class TestConvertShapeCompare(Dy2StTestBase): - @test_legacy_and_pt_and_pir - def test_non_variable(self): - self.assertEqual( - paddle.jit.dy2static.convert_shape_compare(1, "<", 2), True - ) - self.assertEqual( - paddle.jit.dy2static.convert_shape_compare(1, "<", 2, "<=", 3), True - ) - self.assertEqual( - paddle.jit.dy2static.convert_shape_compare(1, ">", 2, "<=", 3), - False, - ) - - def error_func(): - """ - Function used to test that comparison doesn't run after first False - """ - raise ValueError("Used for test") - - self.assertEqual( - paddle.jit.dy2static.convert_shape_compare( - 1, ">", 2, "<=", lambda: error_func() - ), - False, - ) - - self.assertEqual( - paddle.jit.dy2static.convert_shape_compare( - 1, "<", 2, "in", [1, 2, 3] - ), - True, - ) - self.assertEqual( - paddle.jit.dy2static.convert_shape_compare( - 1, "<", 2, "not in", [1, 2, 3] - ), - False, - ) - self.assertEqual( - paddle.jit.dy2static.convert_shape_compare(1, "<", 2, "is", 3), - False, - ) - self.assertEqual( - paddle.jit.dy2static.convert_shape_compare( - 1, "<", 2, "is not", [1, 2, 3] - ), - True, - ) - - self.assertEqual( - paddle.jit.dy2static.convert_shape_compare( - [1, 2], "==", [1, 2], "!=", [1, 2, 3] - ), - True, - ) - self.assertEqual( - paddle.jit.dy2static.convert_shape_compare( - [1, 2], "!=", [1, 2, 3], "==", [1, 2] - ), - False, - ) - - def test_variable(self): - paddle.enable_static() - main_program = paddle.static.Program() - startup_program = paddle.static.Program() - with paddle.static.program_guard(main_program, startup_program): - x = paddle.static.data(name='x', shape=[3, 2], dtype='float32') - y = paddle.static.data(name='y', shape=[3, 2], dtype='float32') - self.assertEqual( - paddle.jit.dy2static.convert_shape_compare( - x, "is", x, "is not", y - ), - True, - ) - self.assertEqual( - paddle.jit.dy2static.convert_shape_compare( - x, "is not", x, "is not", y - ), - False, - ) - self.assertEqual( - paddle.jit.dy2static.convert_shape_compare(x, "is", x, "is", y), - False, - ) - - eq_out = paddle.jit.dy2static.convert_shape_compare(x, "==", y) - not_eq_out = paddle.jit.dy2static.convert_shape_compare(x, "!=", y) - long_eq_out = paddle.jit.dy2static.convert_shape_compare( - x, "==", x, "!=", y - ) - - place = ( - paddle.CUDAPlace(0) - if paddle.is_compiled_with_cuda() - else paddle.CPUPlace() - ) - exe = paddle.static.Executor(place) - x_y_eq_out = exe.run( - feed={ - "x": np.ones([3, 2]).astype(np.float32), - "y": np.ones([3, 2]).astype(np.float32), - }, - fetch_list=[eq_out, not_eq_out, long_eq_out], - ) - np.testing.assert_array_equal( - np.array(x_y_eq_out), np.array([True, False, False]) - ) - - set_a_zero = np.ones([3, 2]).astype(np.float32) - set_a_zero[0][0] = 0.0 - x_y_not_eq_out = exe.run( - feed={"x": np.ones([3, 2]).astype(np.float32), "y": set_a_zero}, - fetch_list=[eq_out, not_eq_out, long_eq_out], - ) - np.testing.assert_array_equal( - np.array(x_y_not_eq_out), np.array([False, True, True]) - ) - paddle.disable_static() - - class ShapeLayer(paddle.nn.Layer): def __init__(self): super().__init__()
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/advisories/GHSA-3cr5-2446-8pg3ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2023-52314ghsaADVISORY
- github.com/PaddlePaddle/Paddle/blob/develop/security/advisory/pdsa-2023-023.mdghsaWEB
- github.com/PaddlePaddle/Paddle/commit/5ed9478fdef96a06eeec9093f9e768c97b094af3ghsaWEB
- github.com/pypa/advisory-database/tree/main/vulns/paddlepaddle/PYSEC-2024-146.yamlghsaWEB
News mentions
0No linked articles in our index yet.