TensorFlow Python Code Injection: More eval() Woes
Background
JFrog security research team (formerly Vdoo) has recently disclosed a code injection issue in one of the utilities shipped with TensorFlow, a popular Machine Learning platform that’s widely used in the industry. The issue has been assigned to CVE-2021-41228.
Read more about our previous, similar disclosure in Yamale in our previous blog post.
The injection issue
The issue lies in the saved_model_cli tool, which is used to save a model’s state.
An attacker that can control the contents of the --input_examples argument, can provide a malicious input that runs arbitrary Python code.
The underlying issue lies in the preprocess_input_examples_arg_string function:
def preprocess_input_examples_arg_string(input_examples_str):
    input_dict = preprocess_input_exprs_arg_string(input_examples_str)
        ...which calls preprocess_input_exprs_arg_string, that contains the vulnerable call:
def preprocess_input_exprs_arg_string(input_exprs_str):
    input_dict = {}
  for input_raw in filter(bool, input_exprs_str.split(';')):
      ...
        input_key, expr = input_raw.split('=', 1)
      # ast.literal_eval does not work with numpy expressions
      input_dict[input_key] = eval(expr)  # pylint: disable=eval-used
  return input_dictIn our case, input_exprs_str is the user’s input coming from the command line argument.
We can see that arbitrary input is flowing to eval, which leads to code injection.
Since the --input_examples option takes only a list of dictionaries, it is unexpected by the end-user (and undocumented by the vendor) that arbitrary input can lead to code injection.
TensorFlow’s fix
The issue was fixed in TensorFlow 2.7.0, we urge anyone using the saved_model_cli tool  to upgrade to this version.
Since the --input_examples option should only accept a list of dictionaries, the eval call was replaced with a call to json.loads, which accepts a list of dictionaries and is safe for use with arbitrary unfiltered input.
Can we exploit it remotely?
As mentioned in our previous blogpost , these issues might be remotely exploitable (in a reasonable scenario) in the context of a parameter injection attack. See our previous blogpost for more details.
Acknowledgements
We would like to thank TensorFlow’s maintainers, for validating and fixing the issue in a prompt manner and responsibly creating a CVE for the issue after the fixed version was available.
 
  
 
                     
                      