yaml_load.py 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. #
  2. # Copyright (c) 2016 Rackspace, Inc.
  3. #
  4. # SPDX-License-Identifier: Apache-2.0
  5. r"""
  6. ===============================
  7. B506: Test for use of yaml load
  8. ===============================
  9. This plugin test checks for the unsafe usage of the ``yaml.load`` function from
  10. the PyYAML package. The yaml.load function provides the ability to construct
  11. an arbitrary Python object, which may be dangerous if you receive a YAML
  12. document from an untrusted source. The function yaml.safe_load limits this
  13. ability to simple Python objects like integers or lists.
  14. Please see
  15. https://pyyaml.org/wiki/PyYAMLDocumentation#LoadingYAML for more information
  16. on ``yaml.load`` and yaml.safe_load
  17. :Example:
  18. .. code-block:: none
  19. >> Issue: [yaml_load] Use of unsafe yaml load. Allows instantiation of
  20. arbitrary objects. Consider yaml.safe_load().
  21. Severity: Medium Confidence: High
  22. CWE: CWE-20 (https://cwe.mitre.org/data/definitions/20.html)
  23. Location: examples/yaml_load.py:5
  24. 4 ystr = yaml.dump({'a' : 1, 'b' : 2, 'c' : 3})
  25. 5 y = yaml.load(ystr)
  26. 6 yaml.dump(y)
  27. .. seealso::
  28. - https://pyyaml.org/wiki/PyYAMLDocumentation#LoadingYAML
  29. - https://cwe.mitre.org/data/definitions/20.html
  30. .. versionadded:: 1.0.0
  31. .. versionchanged:: 1.7.3
  32. CWE information added
  33. """
  34. import bandit
  35. from bandit.core import issue
  36. from bandit.core import test_properties as test
  37. @test.test_id("B506")
  38. @test.checks("Call")
  39. def yaml_load(context):
  40. imported = context.is_module_imported_exact("yaml")
  41. qualname = context.call_function_name_qual
  42. if not imported and isinstance(qualname, str):
  43. return
  44. qualname_list = qualname.split(".")
  45. func = qualname_list[-1]
  46. if all(
  47. [
  48. "yaml" in qualname_list,
  49. func == "load",
  50. not context.check_call_arg_value("Loader", "SafeLoader"),
  51. not context.check_call_arg_value("Loader", "CSafeLoader"),
  52. not context.get_call_arg_at_position(1) == "SafeLoader",
  53. not context.get_call_arg_at_position(1) == "CSafeLoader",
  54. ]
  55. ):
  56. return bandit.Issue(
  57. severity=bandit.MEDIUM,
  58. confidence=bandit.HIGH,
  59. cwe=issue.Cwe.IMPROPER_INPUT_VALIDATION,
  60. text="Use of unsafe yaml load. Allows instantiation of"
  61. " arbitrary objects. Consider yaml.safe_load().",
  62. lineno=context.node.lineno,
  63. )