CVE-2022-45908: Improper Control of Generation of Code ('Code Injection') (CWE-94)
value: In PaddlePaddle before 2.4, paddle.audio.functional.get_window is vulnerable to code injection because it calls eval on a user-supplied winstr. This may lead to arbitrary code execution.
CWE description: The product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.
CVSS v3 base score: 9.8
Published: 2022-11-26T02:15Z
Repository: https://github.com/PaddlePaddle/Paddle
Language: Python
Files changed: python/paddle/audio/functional/window.py
Commit date: 2022-10-28 18:15:55 +0800
Commit message: [audio]fix audio get_window security error (#47386)

* fix window security error

* format
Diff: diff --git a/python/paddle/audio/functional/window.py b/python/paddle/audio/functional/window.py
index 844e2fc263..315d5a50a3 100644
--- a/python/paddle/audio/functional/window.py
+++ b/python/paddle/audio/functional/window.py
@@ -17,45 +17,70 @@ from typing import Union
 
 import paddle
 from paddle import Tensor
 
 
+class WindowFunctionRegister(object):
+    def __init__(self):
+        self._functions_dict = dict()
+
+    def register(self, func=None):
+        def add_subfunction(func):
+            name = func.__name__
+            self._functions_dict[name] = func
+            return func
+
+        return add_subfunction
+
+    def get(self, name):
+        return self._functions_dict[name]
+
+
+window_function_register = WindowFunctionRegister()
+
+
+@window_function_register.register()
 def _cat(x: List[Tensor], data_type: str) -> Tensor:
     l = [paddle.to_tensor(_, data_type) for _ in x]
     return paddle.concat(l)
 
 
+@window_function_register.register()
 def _acosh(x: Union[Tensor, float]) -> Tensor:
     if isinstance(x, float):
         return math.log(x + math.sqrt(x**2 - 1))
     return paddle.log(x + paddle.sqrt(paddle.square(x) - 1))
 
 
+@window_function_register.register()
 def _extend(M: int, sym: bool) -> bool:
     """Extend window by 1 sample if needed for DFT-even symmetry."""
     if not sym:
         return M + 1, True
     else:
         return M, False
 
 
+@window_function_register.register()
 def _len_guards(M: int) -> bool:
     """Handle small or incorrect window lengths."""
     if int(M) != M or M < 0:
         raise ValueError('Window length M must be a non-negative integer')
 
     return M <= 1
 
 
+@window_function_register.register()
 def _truncate(w: Tensor, needed: bool) -> Tensor:
     """Truncate window by 1 sample if needed for DFT-even symmetry."""
     if needed:
         return w[:-1]
     else:
         return w
 
 
+@window_function_register.register()
 def _general_gaussian(
     M: int, p, sig, sym: bool = True, dtype: str = 'float64'
 ) -> Tensor:
     """Compute a window with a generalized Gaussian shape.
     This function is consistent with scipy.signal.windows.general_gaussian().
@@ -68,10 +93,11 @@ def _general_gaussian(
     w = paddle.exp(-0.5 * paddle.abs(n / sig) ** (2 * p))
 
     return _truncate(w, needs_trunc)
 
 
+@window_function_register.register()
 def _general_cosine(
     M: int, a: float, sym: bool = True, dtype: str = 'float64'
 ) -> Tensor:
     """Compute a generic weighted sum of cosine terms window.
     This function is consistent with scipy.signal.windows.general_cosine().
@@ -84,19 +110,21 @@ def _general_cosine(
     for k in range(len(a)):
         w += a[k] * paddle.cos(k * fac)
     return _truncate(w, needs_trunc)
 
 
+@window_function_register.register()
 def _general_hamming(
     M: int, alpha: float, sym: bool = True, dtype: str = 'float64'
 ) -> Tensor:
     """Compute a generalized Hamming window.
     This function is consistent with scipy.signal.windows.general_hamming()
     """
     return _general_cosine(M, [alpha, 1.0 - alpha], sym, dtype=dtype)
 
 
+@window_function_register.register()
 def _taylor(
     M: int, nbar=4, sll=30, norm=True, sym: bool = True, dtype: str = 'float64'
 ) -> Tensor:
     """Compute a Taylor window.
     The Taylor window taper function approximates the Dolph-Chebyshev window's
@@ -149,26 +177,29 @@ def _taylor(
         w *= scale
     w = w.squeeze()
     return _truncate(w, needs_trunc)
 
 
+@window_function_register.register()
 def _hamming(M: int, sym: bool = True, dtype: str = 'float64') -> Tensor:
     """Compute a Hamming window.
     The Hamming window is a taper formed by using a raised cosine with
     non-zero endpoints, optimized to minimize the nearest side lobe.
     """
     return _general_hamming(M, 0.54, sym, dtype=dtype)
 
 
+@window_function_register.register()
 def _hann(M: int, sym: bool = True, dtype: str = 'float64') -> Tensor:
     """Compute a Hann window.
     The Hann window is a taper formed by using a raised cosine or sine-squared
     with ends that touch zero.
     """
     return _general_hamming(M, 0.5, sym, dtype=dtype)
 
 
+@window_function_register.register()
 def _tukey(
     M: int, alpha=0.5, sym: bool = True, dtype: str = 'float64'
 ) -> Tensor:
     """Compute a Tukey window.
     The Tukey window is also known as a tapered cosine window.
@@ -198,19 +229,21 @@ def _tukey(
     w = paddle.concat([w1, w2, w3])
 
     return _truncate(w, needs_trunc)
 
 
+@window_function_register.register()
 def _kaiser(
     M: int, beta: float, sym: bool = True, dtype: str = 'float64'
 ) -> Tensor:
     """Compute a Kaiser window.
     The Kaiser window is a taper formed by using a Bessel function.
     """
     raise NotImplementedError()
 
 
+@window_function_register.register()
 def _gaussian(
     M: int, std: float, sym: bool = True, dtype: str = 'float64'
 ) -> Tensor:
     """Compute a Gaussian window.
     The Gaussian widows has a Gaussian shape defined by the standard deviation(std).
@@ -224,10 +257,11 @@ def _gaussian(
     w = paddle.exp(-(n**2) / sig2)
 
     return _truncate(w, needs_trunc)
 
 
+@window_function_register.register()
 def _exponential(
     M: int, center=None, tau=1.0, sym: bool = True, dtype: str = 'float64'
 ) -> Tensor:
     """Compute an exponential (or Poisson) window."""
     if sym and center is not None:
@@ -243,10 +277,11 @@ def _exponential(
     w = paddle.exp(-paddle.abs(n - center) / tau)
 
     return _truncate(w, needs_trunc)
 
 
+@window_function_register.register()
 def _triang(M: int, sym: bool = True, dtype: str = 'float64') -> Tensor:
     """Compute a triangular window."""
     if _len_guards(M):
         return paddle.ones((M,), dtype=dtype)
     M, needs_trunc = _extend(M, sym)
@@ -260,10 +295,11 @@ def _triang(M: int, sym: bool = True, dtype: str = 'float64') -> Tensor:
         w = paddle.concat([w, w[-2::-1]])
 
     return _truncate(w, needs_trunc)
 
 
+@window_function_register.register()
 def _bohman(M: int, sym: bool = True, dtype: str = 'float64') -> Tensor:
     """Compute a Bohman window.
     The Bohman window is the autocorrelation of a cosine window.
     """
     if _len_guards(M):
@@ -277,20 +313,22 @@ def _bohman(M: int, sym: bool = True, dtype: str = 'float64') -> Tensor:
     w = _cat([0, w, 0], dtype)
 
     return _truncate(w, needs_trunc)
 
 
+@window_function_register.register()
 def _blackman(M: int, sym: bool = True, dtype: str = 'float64') -> Tensor:
     """Compute a Blackman window.
     The Blackman window is a taper formed by using the first three terms of
     a summation of cosines. It was designed to have close to the minimal
     leakage possible.  It is close to optimal, only slightly worse than a
     Kaiser window.
     """
     return _general_cosine(M, [0.42, 0.50, 0.08], sym, dtype=dtype)
 
 
+@window_function_register.register()
 def _cosine(M: int, sym: bool = True, dtype: str = 'float64') -> Tensor:
     """Compute a window with a simple cosine shape."""
     if _len_guards(M):
         return paddle.ones((M,), dtype=dtype)
     M, needs_trunc = _extend(M, sym)
@@ -306,11 +344,11 @@ def get_window(
     dtype: str = 'float64',
 ) -> Tensor:
     """Return a window of a given length and type.
 
     Args:
-        window (Union[str, Tuple[str, float]]): The window function applied to the signal before the Fourier transform. Supported window functions: 'hamming', 'hann', 'kaiser', 'gaussian', 'exponential', 'triang', 'bohman', 'blackman', 'cosine', 'tukey', 'taylor'.
+        window (Union[str, Tuple[str, float]]): The window function applied to the signal before the Fourier transform. Supported window functions: 'hamming', 'hann', 'kaiser', 'gaussian', 'general_gaussian', 'exponential', 'triang', 'bohman', 'blackman', 'cosine', 'tukey', 'taylor'.
         win_length (int): Number of samples.
         fftbins (bool, optional): If True, create a "periodic" window. Otherwise, create a "symmetric" window, for use in filter design. Defaults to True.
         dtype (str, optional): The data type of the return window. Defaults to 'float64'.
 
     Returns:
@@ -346,12 +384,12 @@ def get_window(
         raise ValueError(
             "%s as window type is not supported." % str(type(window))
         )
 
     try:
-        winfunc = eval('_' + winstr)
-    except NameError as e:
+        winfunc = window_function_register.get('_' + winstr)
+    except KeyError as e:
         raise ValueError("Unknown window type.") from e
 
     params = (win_length,) + args
     kwargs = {'sym': sym}
     return winfunc(*params, dtype=dtype, **kwargs)

Vulnerable code:         window (Union[str, Tuple[str, float]]): The window function applied to the signal before the Fourier transform. Supported window functions: 'hamming', 'hann', 'kaiser', 'gaussian', 'exponential', 'triang', 'bohman', 'blackman', 'cosine', 'tukey', 'taylor'.
        winfunc = eval('_' + winstr)
    except NameError as e:
Fixed code: class WindowFunctionRegister(object):
    def __init__(self):
        self._functions_dict = dict()

    def register(self, func=None):
        def add_subfunction(func):
            name = func.__name__
            self._functions_dict[name] = func
            return func

        return add_subfunction

    def get(self, name):
        return self._functions_dict[name]


window_function_register = WindowFunctionRegister()


@window_function_register.register()
@window_function_register.register()
@window_function_register.register()
@window_function_register.register()
@window_function_register.register()
@window_function_register.register()
@window_function_register.register()
@window_function_register.register()
@window_function_register.register()
@window_function_register.register()
@window_function_register.register()
@window_function_register.register()
@window_function_register.register()
@window_function_register.register()
@window_function_register.register()
@window_function_register.register()
@window_function_register.register()
@window_function_register.register()
@window_function_register.register()
        window (Union[str, Tuple[str, float]]): The window function applied to the signal before the Fourier transform. Supported window functions: 'hamming', 'hann', 'kaiser', 'gaussian', 'general_gaussian', 'exponential', 'triang', 'bohman', 'blackman', 'cosine', 'tukey', 'taylor'.
        winfunc = window_function_register.get('_' + winstr)
    except KeyError as e: