CVE-2023-22799 - ReDoS-based DoS Vulnerability in GlobalID (`<1..1`): Exploit Details and How to Fix
---
Table of Contents
What Is CVE-2023-22799?
CVE-2023-22799 is a serious Regular Expression Denial of Service (ReDoS) vulnerability discovered in the GlobalID Ruby gem (versions before 1..1). This bug allows attackers to submit specially crafted input, causing your server to hang as it processes a poorly-written regular expression for an unexpectedly long time.
Understanding ReDoS Attacks
ReDoS stands for Regular Expression Denial of Service. It happens when a regex (a string-matching pattern) is written in a way that can take a very long time to check some inputs—especially "evil" ones an attacker can make on purpose.
Why is it bad?
A single malicious HTTP request can hang your web server for several seconds or more, blocking real users and potentially crashing your app.
How Does This Affect GlobalID?
The GlobalID gem (before v1..1) uses a regular expression to parse input strings. If an attacker sends a specially crafted string, the regex engine gets stuck trying to process it, eating CPU and causing a denial of service.
The Vulnerable Code
The vulnerable regex can be found in GlobalID's parser:
def parse(str)
# Vulnerable regex here:
match = str.match(/\A([A-Za-z-9]+(?:-[A-Za-z-9]+)*):(.+)\z/)
# ...
end
At first glance, this looks innocent. But the repeated group with (?:-[A-Za-z-9]+)* combined with certain input can cause "catastrophic backtracking"—meaning the engine tries way too many alternatives before failing.
If an attacker sends a string like
A-A-A-A...A:payload
But with a massive number of repeating segments, the regex engine will get stuck trying all possible groupings. The more segments, the longer it takes.
Example of Evil Input
# This will hang the server!
payload = "A-" * 100_000 + ":attack"
Here's a short Ruby demo showing the danger
def vulnerable_parse(str)
regex = /\A([A-Za-z-9]+(?:-[A-Za-z-9]+)*):(.+)\z/
str.match(regex)
end
long_str = "A-" * 60_000 + ":pwned"
start = Time.now
vulnerable_parse(long_str)
puts "Time taken: #{Time.now - start} seconds"
Output:
This code can easily take minutes or hours, freezing your app!
1. Upgrade
Upgrade to GlobalID 1..1 or newer.
See the official release notes.
bundle update globalid
Pre-validate input: Use a simple check BEFORE passing to the vulnerable regex.
- Backport the fix: Apply the patch from v1..1 to your version.
Example workaround (limit input length)
def safe_parse(str)
raise "Input too long" if str.length > 100
regex = /\A([A-Za-z-9]+(?:-[A-Za-z-9]+)*):(.+)\z/
str.match(regex)
end
References & Further Reading
- GlobalID: v1..1 Release Fixing ReDoS
- Security Advisory (GHSA-7xwj-9wr3-r9wr)
- GlobalID Commit Patch
- OWASP: Regular Expression Denial of Service (ReDoS)
Final Thoughts
CVE-2023-22799 is a textbook example of how even a simple regular expression, if not careful, can open your app to denial-of-service. The fix is easy: upgrade today or apply a strict workaround.
Got questions, want help upgrading, or not sure if you're affected?
Timeline
Published on: 02/09/2023 20:15:00 UTC
Last modified on: 02/16/2023 20:18:00 UTC