This is completely unexpected for a developer looking for a simple way to pass around data, only to find out that executable code could be included as well. Nowadays, people will use yaml.safe_load(), but there’s still a lot of yaml.load() going on. Stay safe. Always use safe_load(). And avoid pickles!
Ruby: Speed can kill
What about Ruby? It’s also extremely popular as a language for web applications, in particular due to Ruby on Rails. It’s also useful in DevOps as the underlying language for the configuration management tool Chef. The aforementioned YAML problem also exists in Ruby—and in all YAML-compliant parsers, regardless of language. But there’s more.
You might think that if you are using XML with a Rails app, you’d be safe from this YAML silliness (and maybe be more worried about XXE). But in 2013 (CVE-2013-0156), people realized that Rails allowed the embedding of YAML within XML by way of any element with the attribute type=”yaml”.
You can guess what happened: All the problems with YAML end up as problems with XML.
The issue goes beyond data formats. Ruby/Rails opens up other possibilities due to the way it handles strings. One elegant exploit from last year turned what appeared to be directory traversal into something more. CVE-2016-0752 affected releases before Rails 18.104.22.168, and allowed file traversal via render. Being able to grab any arbitrary file on the host was dangerous enough, but render actually evaluated the file.
Sample code is as follows:
def show render params[:template] end
So one can leverage this behavior into more than just getting files off the machine. A bad actor can get an executable that can be evaluated into a file on that machine. The simplest way to accomplish that is to make the server log the malicious payload.