CVE-2009-5147
High · 7.3CVSS
7.3
EPSS
7.8%
Published
Mar 29, 2017
CISA due date
—
Cloudanix analysis
An older version of Ruby can be tricked into loading and running attacker-written code if a program accepts untrusted input that names a library file.
- Exploitation
- Remote Unauthenticated
- Attacker needs
- None
- Complexity
- Low
- Impact
- Remote Code Execution
- Component
- Library
- Class
- Improper Input Validation
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
DL::dlopen accepts and resolves library paths derived from tainted strings, bypassing Ruby's taint checks and enabling load of attacker-controlled shared objects that execute arbitrary code during symbol resolution.
Why it matters to the business
Applications built on the listed Ruby releases can be tricked into executing attacker-supplied native code, leading to full host compromise, data theft, or service disruption; the issue affects a wide range of legacy Ruby deployments still present in many environments.
How an attack unfolds
An attacker supplies a tainted string containing a malicious library path or name to any code path that reaches DL::dlopen; Ruby resolves and loads the library without sanitization, the library's initialization routines run with the privileges of the Ruby process, and the attacker gains code execution.
How to fix it
Upgrade Ruby to a release that enforces taint checks inside DL::dlopen (1.8 branch after the relevant patch, 1.9.3 patchlevel 648 or later, 2.0.0 patchlevel 648 or later, 2.1.8 or later); where upgrade is impossible, remove or wrap all direct calls to DL::dlopen and avoid passing untrusted strings to any FFI or dynamic-loading API.
How to confirm the fix worked
After patching, confirm that attempts to pass tainted strings to dlopen raise SecurityError; scan source and gem code for direct or indirect use of DL.dlopen, Fiddle::Function, or similar APIs and ensure all path arguments are untainted or explicitly validated.
Typical attack path
- Identify an application endpoint or input that reaches DL::dlopen with user-controlled data
- Craft a tainted library name or path that points to attacker-controlled object code
- Trigger the dlopen call so Ruby loads the malicious library
- Execute native code from the library's constructors or exported functions
How to detect it
Review web-application or script logs for unexpected library names or paths containing user input; look for child processes spawned by Ruby that load shared objects from temporary or user-controlled directories; examine core dumps or strace output for dlopen calls with tainted arguments.
What your security team should do
- Inventory all Ruby 1.8–2.1 installations and schedule immediate upgrades to supported releases
- Add static-analysis rules that flag any use of DL::dlopen or equivalent dynamic loaders
- Block execution of unexpected .so/.dll files from application-writable directories via OS-level policies
The record
DL::dlopen in Ruby 1.8, 1.9.0, 1.9.2, 1.9.3, 2.0.0 before patchlevel 648, and 2.1 before 2.1.8 opens libraries with tainted names.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|---|---|---|
| Debian:6.0 | ruby1.8 | 0 | 1.8.7.302-2squeeze5 |
| Debian:6.0 | ruby1.9.1 | 0 | 1.9.2.0-2+deb6u7 |
| Red Hat:rhel_software_collections:3::el6 | rh-ruby22-ruby | 0 | 0:2.2.9-19.el6 |
| Red Hat:rhel_software_collections:3::el6 | rh-ruby22-ruby-debuginfo | 0 | 0:2.2.9-19.el6 |
| Red Hat:rhel_software_collections:3::el6 | rh-ruby22-ruby-devel | 0 | 0:2.2.9-19.el6 |
| Red Hat:rhel_software_collections:3::el6 | rh-ruby22-ruby-doc | 0 | 0:2.2.9-19.el6 |
| Red Hat:rhel_software_collections:3::el6 | rh-ruby22-ruby-irb | 0 | 0:2.2.9-19.el6 |
| Red Hat:rhel_software_collections:3::el6 | rh-ruby22-ruby-libs | 0 | 0:2.2.9-19.el6 |
| Red Hat:rhel_software_collections:3::el6 | rh-ruby22-ruby-tcltk | 0 | 0:2.2.9-19.el6 |
| Red Hat:rhel_software_collections:3::el6 | rh-ruby22-rubygem-bigdecimal | 0 | 0:1.2.6-19.el6 |
| Red Hat:rhel_software_collections:3::el6 | rh-ruby22-rubygem-io-console | 0 | 0:0.4.3-19.el6 |
| Red Hat:rhel_software_collections:3::el6 | rh-ruby22-rubygem-json | 0 | 0:1.8.1.1-19.el6 |
| Red Hat:rhel_software_collections:3::el6 | rh-ruby22-rubygem-minitest | 0 | 0:5.4.3-19.el6 |
| Red Hat:rhel_software_collections:3::el6 | rh-ruby22-rubygem-power_assert | 0 | 0:0.2.2-19.el6 |
| Red Hat:rhel_software_collections:3::el6 | rh-ruby22-rubygem-psych | 0 | 0:2.0.8.1-19.el6 |
| Red Hat:rhel_software_collections:3::el6 | rh-ruby22-rubygem-rake | 0 | 0:10.4.2-19.el6 |
| Red Hat:rhel_software_collections:3::el6 | rh-ruby22-rubygem-rdoc | 0 | 0:4.2.0-19.el6 |
| Red Hat:rhel_software_collections:3::el6 | rh-ruby22-rubygem-test-unit | 0 | 0:3.0.8-19.el6 |
| Red Hat:rhel_software_collections:3::el6 | rh-ruby22-rubygems | 0 | 0:2.4.5.4-19.el6 |
| Red Hat:rhel_software_collections:3::el6 | rh-ruby22-rubygems-devel | 0 | 0:2.4.5.4-19.el6 |
| Red Hat:rhel_software_collections:3::el7 | rh-ruby22-ruby | 0 | 0:2.2.9-19.el7 |
| Red Hat:rhel_software_collections:3::el7 | rh-ruby22-ruby-debuginfo | 0 | 0:2.2.9-19.el7 |
| Red Hat:rhel_software_collections:3::el7 | rh-ruby22-ruby-devel | 0 | 0:2.2.9-19.el7 |
| Red Hat:rhel_software_collections:3::el7 | rh-ruby22-ruby-doc | 0 | 0:2.2.9-19.el7 |
| Red Hat:rhel_software_collections:3::el7 | rh-ruby22-ruby-irb | 0 | 0:2.2.9-19.el7 |
| Red Hat:rhel_software_collections:3::el7 | rh-ruby22-ruby-libs | 0 | 0:2.2.9-19.el7 |
| Red Hat:rhel_software_collections:3::el7 | rh-ruby22-ruby-tcltk | 0 | 0:2.2.9-19.el7 |
| Red Hat:rhel_software_collections:3::el7 | rh-ruby22-rubygem-bigdecimal | 0 | 0:1.2.6-19.el7 |
| Red Hat:rhel_software_collections:3::el7 | rh-ruby22-rubygem-io-console | 0 | 0:0.4.3-19.el7 |
| Red Hat:rhel_software_collections:3::el7 | rh-ruby22-rubygem-json | 0 | 0:1.8.1.1-19.el7 |
| Red Hat:rhel_software_collections:3::el7 | rh-ruby22-rubygem-minitest | 0 | 0:5.4.3-19.el7 |
| Red Hat:rhel_software_collections:3::el7 | rh-ruby22-rubygem-power_assert | 0 | 0:0.2.2-19.el7 |
| Red Hat:rhel_software_collections:3::el7 | rh-ruby22-rubygem-psych | 0 | 0:2.0.8.1-19.el7 |
| Red Hat:rhel_software_collections:3::el7 | rh-ruby22-rubygem-rake | 0 | 0:10.4.2-19.el7 |
| Red Hat:rhel_software_collections:3::el7 | rh-ruby22-rubygem-rdoc | 0 | 0:4.2.0-19.el7 |
| Red Hat:rhel_software_collections:3::el7 | rh-ruby22-rubygem-test-unit | 0 | 0:3.0.8-19.el7 |
| Red Hat:rhel_software_collections:3::el7 | rh-ruby22-rubygems | 0 | 0:2.4.5.4-19.el7 |
| Red Hat:rhel_software_collections:3::el7 | rh-ruby22-rubygems-devel | 0 | 0:2.4.5.4-19.el7 |
| SUSE:Studio Onsite 1.3 | ruby19 | 0 | 1.9.3.p392-0.23.1 |
| Ubuntu:14.04:LTS | ruby1.9.1 | 0 | 1.9.3.484-2ubuntu1.3 |
| Ubuntu:14.04:LTS | ruby2.0 | 0 | 2.0.0.484-1ubuntu2.4 |
| Ubuntu:16.04:LTS | ruby2.3 | 0 | 2.3.1-2~16.04.2 |
Related vulnerabilities
- CVE-2014-8090 The REXML parser in Ruby 1.9.x before 1.9.3 patchlevel 551, 2.0.x before 2.0.0 patchlevel… Also affects ruby1.8
- CVE-2013-4164 Heap-based buffer overflow in Ruby 1.8, 1.9 before 1.9.3-p484, 2.0 before 2.0.0-p353, 2.1… Also affects ruby1.8
- CVE-2014-4975 Off-by-one error in the encodes function in pack.c in Ruby 1.9.3 and earlier, and 2.x… Also affects ruby1.9.1
- CVE-2013-0269 The JSON gem before 1.5.5, 1.6.x before 1.6.8, and 1.7.x before 1.7.7 for Ruby allows… Also affects ruby1.9.1
- CVE-2017-17405 Ruby before 2.4.3 allows Net::FTP command injection. Also affects rh-ruby22-ruby
- CVE-2017-0903 RubyGems versions between 2.0.0 and 2.6.13 are vulnerable to a possible remote code… Also affects rh-ruby22-ruby
- CVE-2017-10784 The Basic authentication code in WEBrick library in Ruby before 2.2.8, 2.3.x before… Also affects rh-ruby22-ruby
- CVE-2017-0898 Ruby before 2.4.2, 2.3.5, and 2.2.8 is vulnerable to a malicious format string which… Also affects rh-ruby22-ruby