VYPR
Critical severityNVD Advisory· Published Jan 3, 2024· Updated Nov 14, 2024

Command injection in convert_shape_compare

CVE-2023-52314

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.

PackageAffected versionsPatched versions
PaddlePaddlePyPI
< 2.6.02.6.0

Affected products

2

Patches

1
5ed9478fdef9

[Dy2St]Fix BUG with Potential security vulnerabilities (#60097)

https://github.com/PaddlePaddle/PaddleAurelius84Dec 18, 2023via ghsa
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

News mentions

0

No linked articles in our index yet.