Recently,
it was disclosed that libyaml <= 0.1.4 is vulnerable to a
heap overflow [1]. libyaml is used by Ruby's Psych YAML parser
[2], which ships with Ruby >= 1.9.2 and was made the default
YAML parser in Ruby 1.9.3.
## Vulnerability
The heap overflow occurs in yaml_parser_scan_tag_uri() in
scanner.c when parsing a specially crafted tag. The solution was
to limit the maximum length of input [3] and and use size types
instead of int [4].
## Risk
Heap overflows can and eventually are used to gain arbitrary
code execution via techniques such as overwriting next/prev
pointers in the heap chunk list [5].
After the YAML serialization vulnerabilities [6], Rails removed
YAML from the list of acceptable serialization formats. However,
YAML is still used in many places, such as configuration files
and by RubyGems to serialize Gem::Specification objects. While
it may not be as simple as sending an HTTP request containing
malicious YAML to a Rails app, it is still possible for an
attacker to exploit this vulnerability and gain arbitrary code
execution on the target's system.
Any
software that uses an unpatched version of libyaml <= 0.1.4
is vulnerable. This includes, but is not limited to, the Psych
YAML parser, which is included in Ruby >= 1.9.2.
## Exploit
No public exploits currently exist, though this may change.
## Check if you’re Vulnerable
To check which version of libyaml that Psych is using, run the
following:
ruby -r yaml -e 'puts Psych::LIBYAML_VERSION'
The vulnerability is patched in libyaml version 0.1.5.
Debian, RedHat, Ubuntu and Fedora have released their own patched versions of libyaml 0.1.4, so Psych::LIBYAML_VERSION may still be 0.1.4 on a patched system. See below for distribution-specific information:
###
RVM
Users who installed Ruby via RVM, but whose package manager does
not provide a libyaml package, are vulnerable. RVM will attempt
to install libyaml from the system's package manager, and will
fallback to install libyaml 0.1.4 from source [7].
### rbenv/ruby-build
Users who installed Ruby via rbenv/ruby-build, but a) did not
install libyaml via homebrew b) or do not use homebrew, are
vulnerable. This is due to ruby-build bundling libyaml 0.1.4 –
unless libyaml was installed separately via homebrew [8].
### Compiled from Source (Ruby >= 2.0.0)
Users who compiled Ruby >= 2.0.0 from source on systems that
lacked libyaml are vulnerable. Starting with Ruby 2.0.0, Psych
vendored libyaml 0.1.4 for when libyaml could not be found on
the system [9].
## Solution
You need to do three things:
1. Upgrade libyaml
2. Upgrade RVM/rbenv/ruby-build and/or recompile rubies
3. Restart Ruby processes
###
Upgrade libyaml
Debian, RedHat, Ubuntu and Fedora have all patched libyaml and
released updated libyaml packages which fix the vulnerability.
The vulnerability has also been fixed upstream and libyaml-0.1.5
has been released. Make sure to *upgrade libyaml* to the latest
version provided by your distribution or to 0.1.5 if you
installed from source.
#### Debian/Ubuntu
Debian and Ubuntu users can update libyaml via apt-get:
apt-get update
apt-get install libyaml-0-2
####
Fedora
Currently, Fedora's updated libyaml packages are still in the
updates-testing repository. To install the updated version of
libyaml, Fedora users must run the following:
yum --enablerepo=updates-testing update libyaml
#### OSX/Homebrew
Users who previously installed libyaml via homebrew must upgrade
to libyaml 0.1.5:
brew update
brew upgrade libyaml
#### Compiled from Source
Users
who previously installed libyaml from source, should install
libyaml 0.1.5:
wget http://pyyaml.org/download/libyaml/yaml-0.1.5.tar.gz
tar -xzvf yaml-0.1.5.tar.gz
cd yaml-0.1.5/
./configure
make
sudo make install
sudo ldconfig # Linux specific
### Recompile Rubies
Depending on how your rubies were installed, you may need to perform steps to upgrade your ruby version manager script and/or rebuild your rubies.
#### Compiled from Source (Ruby >= 2.0.0)
Users who installed Ruby >= 2.0.0 from source, but did not explicitly install libyaml beforehand, must install an updated version of libyaml and re-compile Ruby. This will force Psych to use the system's libyaml instead of its vendored libyaml-0.1.4. This measure will be necessary only until updated versions of ruby 2.0 and 2.1 have been released.
#### RVM
Users who installed Rubies using RVM, but for whom libyaml was
not automatically installed from the package manager, should
simply update RVM. This will cause RVM to update its internal
version of libyaml to 0.1.5. The updated version of libyaml
will then be used for all rubies installed currently and in the
future.
rvm get stable
#### rbenv/ruby-build
Users who installed Rubies using rbenv/ruby-build must first
update ruby-build to >= 20140204 [10] and then re-install any
Rubies built with rbenv/ruby-build.
If ruby-build was installed from homebrew:
brew update
brew upgrade ruby-build
If ruby-build was installed via git:
cd ~/.rbenv/plugins/ruby-build
git pull
To re-install all Rubies installed by rbenv:
for ruby in ~/.rbenv/versions/*; do
rbenv uninstall $ruby
rbenv install $ruby
done
This will force ruby-build to re-compile all previously installed Rubies against libyaml 0.1.5.
### Restart Ruby processes
In order for the Ruby processes to load the updated libyaml, they must be restarted.
## Credits
The vulnerability was originally discovered by Florian Weimer of the Red Hat Product Security Team. Thanks to Michal Papis for helping to get the vulnerability fixed in upstream.
## About Us
RubySec (http://rubysec.com) is an informal group of Ruby developers and security professionals interested in providing security resources to the Ruby community. We also maintain ruby-advisory-db (https://github.com/rubysec/ruby-advisory-db#readme) and bundler-audit (https://github.com/rubysec/bundler-audit#readme).
[1]: http://osvdb.org/show/osvdb/102716
[2]: https://github.com/tenderlove/psych#readme
[3]:
https://bitbucket.org/xi/libyaml/commits/0df2fb962294f3a6df1450a3e08c6a0f74f9078c
[4]:
https://bitbucket.org/xi/libyaml/commits/f859ed1eb757a3562b98a28a8ce69274bfd4b3f2
[5]:
http://www.sans.edu/student-files/presentations/heap_overflows_notes.pdf
[6]: https://groups.google.com/forum/#!topic/rubyonrails-security/KtmwSbEpzrU
[7]: https://github.com/wayneeseguin/rvm/issues/2594
[8]: https://github.com/sstephenson/ruby-build/issues/499
[9]: https://bugs.ruby-lang.org/issues/7375
[10]: https://github.com/sstephenson/ruby-build/releases/tag/v20140204
-- Blog: http://postmodern.github.com/ GitHub: https://github.com/postmodern Twitter: @postmodern_mod3 PGP: 0xB9515E77
for ruby in ~/.rbenv/versions/*; do
rbenv uninstall ${ruby##*/}
rbenv install ${ruby##*/}
done
...
[1]: http://osvdb.org/show/osvdb/102716
[2]: <a href="https://github.com/tenderlove/psych#readme" target="_blank" onmousedown="this.href='https://www.goog