Untrusted Mode - Types Whitelist #115

yfeldblum opened this Issue Jan 10, 2013 · 6 comments


3 participants

There ought to be a mechanism to load an untrusted YAML document such that it does not evaluate arbitrary Ruby code, so that YAML may be used as a data interchange format. This likely means having a whitelist of safe classes which can be serialized from and deserialized to in the Untrusted Mode, such as

  • true, false, nil
  • Integer, Float, etc.
  • String
  • Array
  • Hash (with String keys only)

In the Untrusted Mode, no objects may be serialized or deserialized other than those on the whitelist.

The whitelist ought also to be extensible on a per-load and per-dump basis to include extra programmer-defined classes.


tenderlove commented Jan 10, 2013

Can you elaborate? Deserializing YAML does not evaluate arbitrary Ruby code. The recent Rails exploit used YAML to inject arbitrary Ruby code that could be evaluated, but must use a different means besides YAML to evaluate that code. This is similar to Marshal dump / load.

YAML is a popular data format since it is lighter-weight than XML and is less syntax-obtrusive than JSON. It is likely that many people are parsing untrusted YAML documents in addition to trusted YAML documents quite apart from Rails' content-type negotiation and auto-content-parsing mechanisms, using YAML as a data interchange format or API format as an alternative to XML and JSON.

The metasploit exploit for 3.2.10 relies on the YAML parser constructing ruby objects of attacker-chosen classes; the attacker chooses them based on their ability to contribute to running attacker-chosen code. The attack involves a few tricks, but is triggered simply via YAML.load. The exploit not only used YAML to inject the arbitrary Ruby code that could be evaluated, but also used YAML to trigger it being evaluated. I have looked at the metasploit exploit code and replicated it myself using just a crafted YAML document and YAML.load.

The idea here is to offer a way out of this trap by eliminating this vector, while still permitting YAML to be used as a data interchange format with untrusted inputs since it is popular. So that we can safely do this: YAML.in_untrusted_mode_load(params[:yaml_formatted_string]). And be sure that an attacker cannot trick YAML into running attack code - even indirectly by choosing a vulnerable class for the YAML to deserialize.


tenderlove commented Jan 10, 2013

OK! Please investigate a patch. :-)



zzak commented Feb 6, 2013

@yfeldblum will #119 work for you?

@zzak Yes.

zzak closed this Feb 6, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment