CVE-2022-29216 (Python, published 2022-05-21T00:15Z)
Description: value: TensorFlow is an open source platform for machine learning. Prior to versions 2.9.0, 2.8.1, 2.7.2, and 2.6.4, TensorFlow's `saved_model_cli` tool is vulnerable to a code injection. This can be used to open a reverse shell. This code path was maintained for compatibility reasons as the maintainers had several test cases where numpy expressions were used as arguments. However, given that the tool is always run manually, the impact of this is still not severe. The maintainers have now removed the `safe=False` argument, so all parsing is done without calling `eval`. The patch is available in versions 2.9.0, 2.8.1, 2.7.2, and 2.6.4.
Severity: MEDIUM (CVSS v3 base score: 7.8)
Weakness: CWE-94 \u2014 Improper Control of Generation of Code ('Code Injection')
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.
Repository: https://github.com/tensorflow/tensorflow
Files changed:
RELEASE.md
tensorflow/python/tools/saved_model_cli.py
tensorflow/python/tools/saved_model_cli_test.py
Commit message: Remove use of `eval` when evaluating the input example.

Use `ast.eval_literal` instead which safely evaluates the expression.

PiperOrigin-RevId: 400012249
Change-Id: I5ff98608ea2d736d093aa488af723ff4f6707e02


Vulnerable code:
def preprocess_input_exprs_arg_string(input_exprs_str):
    Each input is separated by semicolon. For each input key:
    # ast.literal_eval does not work with numpy expressions
    input_dict[input_key] = eval(expr)  # pylint: disable=eval-used
  input_exprs = preprocess_input_exprs_arg_string(input_exprs_str)
         'numpy module is available as \'np\'. '
         'Will override duplicate input keys from --inputs option.')
        input_expr_str)
    with self.assertRaises(RuntimeError):
      saved_model_cli.preprocess_input_exprs_arg_string(input_str)

Fixed code:
    *   The saved_model_cli's `--input_examples` inputs are now restricted to
        python literals to avoid code injection.
import ast
def preprocess_input_exprs_arg_string(input_exprs_str, safe=True):
      Each input is separated by semicolon. For each input key:
    safe: Whether to evaluate the python expression as literals or allow
      arbitrary calls (e.g. numpy usage).
    if safe:
      try:
        input_dict[input_key] = ast.literal_eval(expr)
      except:
        raise RuntimeError(
            f'Expression "{expr}" is not a valid python literal.')
    else:
      # ast.literal_eval does not work with numpy expressions
      input_dict[input_key] = eval(expr)  # pylint: disable=eval-used
  input_exprs = preprocess_input_exprs_arg_string(input_exprs_str, safe=False)
         'numpy module is available as \'np\'. Please note that the expression '
         'will be evaluated as-is, and is susceptible to code injection. '
         'When this is set, the value will override duplicate input keys from '
         '--inputs option.')
        input_expr_str, safe=False)
  def testInputPreprocessExampleWithCodeInjection(self):
    input_examples_str = 'inputs=os.system("echo hacked")'
    with self.assertRaisesRegex(RuntimeError, 'not a valid python literal.'):
      saved_model_cli.preprocess_input_examples_arg_string(input_examples_str)

    with self.assertRaisesRegex(RuntimeError, 'format is incorrect'):
      saved_model_cli.preprocess_input_exprs_arg_string(input_str, safe=False)