Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Untrusted Mode - Types Whitelist #115

Closed
yfeldblum opened this Issue · 6 comments

3 participants

@yfeldblum

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
Owner

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.

@yfeldblum

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
Owner

OK! Please investigate a patch. :-)

@yfeldblum

Investigating.

@zzak
Collaborator

@yfeldblum will #119 work for you?

@zzak zzak closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.