HerokuEtienne StalmansIncident / postmortem
Ruby CVE-2017-17405: Vulnerability in Ruby’s FTP Implementation
Summary
CVE-2017-17405 affected Ruby’s net/ftp implementation, where a filename returned by an FTP server could reach Ruby’s open function and enable command execution. The issue was found while investigating CVE-2017-8817 in libcurl and checking whether Ruby used libcurl or had a separate FTP implementation with comparable wildcard behavior. Reviewing Ruby 2.4.2 source identified the 1,496-line ftp.rb file and the gettextfile method, which called open(localfile, "w") without validating the value. A proof of concept made an FTP client request a file list containing a pipe-prefixed payload; Ruby passed it to the shell, producing remote code execution and creating a file containing id output. Ruby replaced open with File.open, released the fix in 2.4.3, and assigned CVE-2017-17405; affected versions included Ruby 2.2.8 and earlier, 2.3.5 and earlier, 2.4.2 and earlier, and 2.5.0-preview1.
Context
The investigation began during triage of CVE-2017-8817 in libcurl. After identifying direct libcurl usage, the researchers examined adjacent libraries, motivated in part by the large number of customers using Ruby, to determine whether Ruby used libcurl or had a separate FTP implementation with similar exposure.
Approach / What changed
The researchers downloaded Ruby 2.4.2, searched its source for FTP references, reviewed the net/ftp implementation, and inspected file-opening calls for command-injection risks. They built a Ruby client and a minimal FTP server that returned a pipe-prefixed filename, demonstrating execution through gettextfile. The Ruby team replaced open with File.open.
Takeaways
Ruby’s net/ftp library used open(localfile, "w") in gettextfile, allowing a server-controlled filename beginning with | to trigger command execution.
The proof of concept returned a payload through an FTP NLIST response and caused the connecting client to run echo $(id) > pang.
The fix replaced open with File.open and shipped in Ruby 2.4.3; affected branches included Ruby 2.2.8 and earlier, 2.3.5 and earlier, 2.4.2 and earlier, and Ruby 2.5.0-preview1.
Source and freshness
- Source
- heroku.com
- Published
- Added to Yomu
Summaries are generated from the original by a language model. Check the original before relying on it.
Keep reading
Related reading
The Good Stuff
Paid picks we use ourselves. Links carry a referral code — a subscription through one earns us a commission at no extra cost to you.
The best engineering reads, once a week
One useful email. Unsubscribe anytime.