python.lang.security.deserialization.avoid-pyyaml-load.avoid-pyyaml-load
Community Favorite
semgrep
Author
47,520
Download Count*
License
Detected a possible YAML deserialization vulnerability. yaml.unsafe_load
, yaml.Loader
, yaml.CLoader
, and yaml.UnsafeLoader
are all known to be unsafe methods of deserializing YAML. An attacker with control over the YAML input could create special YAML input that allows the attacker to run arbitrary Python code. This would allow the attacker to steal files, download and install malware, or otherwise take over the machine. Use yaml.safe_load
or yaml.SafeLoader
instead.
Run Locally
Run in CI
Defintion
rules:
- id: avoid-pyyaml-load
metadata:
owasp:
- A08:2017 - Insecure Deserialization
- A08:2021 - Software and Data Integrity Failures
cwe:
- "CWE-502: Deserialization of Untrusted Data"
references:
- https://github.com/yaml/pyyaml/wiki/PyYAML-yaml.load(input)-Deprecation
- https://nvd.nist.gov/vuln/detail/CVE-2017-18342
category: security
technology:
- pyyaml
cwe2022-top25: true
cwe2021-top25: true
subcategory:
- audit
likelihood: LOW
impact: MEDIUM
confidence: MEDIUM
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- "Insecure Deserialization "
languages:
- python
message: Detected a possible YAML deserialization vulnerability.
`yaml.unsafe_load`, `yaml.Loader`, `yaml.CLoader`, and `yaml.UnsafeLoader`
are all known to be unsafe methods of deserializing YAML. An attacker with
control over the YAML input could create special YAML input that allows
the attacker to run arbitrary Python code. This would allow the attacker
to steal files, download and install malware, or otherwise take over the
machine. Use `yaml.safe_load` or `yaml.SafeLoader` instead.
fix-regex:
regex: unsafe_load
replacement: safe_load
count: 1
severity: ERROR
patterns:
- pattern-inside: |
import yaml
...
- pattern-not-inside: |
$YAML = ruamel.yaml.YAML(...)
...
- pattern-either:
- pattern: yaml.unsafe_load(...)
- pattern: yaml.load(..., Loader=yaml.Loader, ...)
- pattern: yaml.load(..., Loader=yaml.UnsafeLoader, ...)
- pattern: yaml.load(..., Loader=yaml.CLoader, ...)
- pattern: yaml.load_all(..., Loader=yaml.Loader, ...)
- pattern: yaml.load_all(..., Loader=yaml.UnsafeLoader, ...)
- pattern: yaml.load_all(..., Loader=yaml.CLoader, ...)
Examples
avoid-pyyaml-load.py
import yaml
#ruleid:avoid-pyyaml-load
yaml.unsafe_load("!!python/object/new:os.system [echo EXPLOIT!]")
def thing(**kwargs):
#ruleid:avoid-pyyaml-load
yaml.unsafe_load("!!python/object/new:os.system [echo EXPLOIT!]", **kwargs)
def other_thing(**kwargs):
#ruleid:avoid-pyyaml-load
yaml.load("!!python/object/new:os.system [echo EXPLOIT!]", Loader=yaml.Loader, **kwargs)
def other_thing_two(**kwargs):
#ruleid:avoid-pyyaml-load
yaml.load("!!python/object/new:os.system [echo EXPLOIT!]", Loader=yaml.UnsafeLoader, **kwargs)
def other_thing_three(**kwargs):
#ruleid:avoid-pyyaml-load
yaml.load("!!python/object/new:os.system [echo EXPLOIT!]", Loader=yaml.CLoader, **kwargs)
def other_thing_four(**kwargs):
#ruleid:avoid-pyyaml-load
yaml.load_all("!!python/object/new:os.system [echo EXPLOIT!]", Loader=yaml.Loader, **kwargs)
def other_thing_five(**kwargs):
#ruleid:avoid-pyyaml-load
yaml.load_all("!!python/object/new:os.system [echo EXPLOIT!]", Loader=yaml.UnsafeLoader, **kwargs)
def other_thing_six(**kwargs):
#ruleid:avoid-pyyaml-load
yaml.load_all("!!python/object/new:os.system [echo EXPLOIT!]", Loader=yaml.CLoader, **kwargs)
def this_is_ok(stream):
#ok:avoid-pyyaml-load
return yaml.load(stream, Loader=yaml.CSafeLoader)
def this_is_also_ok(stream):
#ok:avoid-pyyaml-load
return yaml.load(stream, Loader=yaml.SafeLoader)
def this_is_additionally_ok(stream):
#ok:avoid-pyyaml-load
return yaml.load_all(stream, Loader=yaml.CSafeLoader)
def this_is_ok_too(stream):
#ok:avoid-pyyaml-load
return yaml.load_all(stream, Loader=yaml.SafeLoader)
def this_is_ok_as_well(stream):
#ok:avoid-pyyaml-load
return yaml.load(stream, Loader=yaml.BaseLoader)
def this_is_ok_too_two(stream):
#ok:avoid-pyyaml-load
return yaml.load_all(stream, Loader=yaml.BaseLoader)
def check_ruamel_yaml():
from ruamel.yaml import YAML
yaml = YAML(typ="rt")
# ok:avoid-pyyaml-load
yaml.load("thing.yaml")
# ok:avoid-pyyaml-load
yaml.load_all("thing.yaml")
Short Link: https://sg.run/we9Y