Source: cve@mitre.org
Ruby (aka CRuby) before 1.8.7-p357 computes hash values without restricting the ability to trigger hash collisions predictably, which allows context-dependent attackers to cause a denial of service (CPU consumption) via crafted input to an application that maintains a hash table.
Ruby applications using versions prior to 1.8.7-p357 are vulnerable to a denial-of-service (DoS) attack. By providing crafted input, attackers can trigger predictable hash collisions, leading to excessive CPU consumption and application unavailability, effectively shutting down the service.
Step 1: Payload Preparation: The attacker crafts a malicious input, typically a set of strings designed to hash to the same value within the vulnerable Ruby application's hash table. This requires knowledge of the hash function's behavior (which is predictable in the vulnerable versions).
Step 2: Payload Delivery: The attacker submits the crafted input to the target application. This could be through a web form, API call, or any other input mechanism the application uses to receive data.
Step 3: Hash Collision Trigger: The application processes the malicious input, and the hash function calculates the hash values for each element of the input. Due to the vulnerability, the crafted input elements all hash to the same value.
Step 4: Hash Table Degradation: The application attempts to store the input in the hash table. Because of the collisions, all the input elements are placed in the same 'bucket' of the hash table.
Step 5: CPU Exhaustion: When the application attempts to retrieve or process data from the hash table, it must compare the input against all the elements in the collision bucket. This results in O(n) lookup time, where n is the number of colliding elements. The attacker's crafted input, designed to cause many collisions, forces the application to perform a large number of comparisons, consuming significant CPU resources.
Step 6: Denial of Service: The CPU exhaustion leads to a denial of service. The application becomes unresponsive, unable to process legitimate requests, and potentially crashes or becomes unavailable.
The vulnerability stems from the Ruby interpreter's hash function implementation. Prior to 1.8.7-p357, the hash function did not adequately randomize the hash values generated for different inputs. This lack of randomization allows an attacker to craft input that consistently produces the same hash value, leading to hash collisions. When a hash collision occurs, the application must compare the new input with all existing entries in the hash table with the same hash value, resulting in O(n) lookup time instead of the expected O(1). By repeatedly triggering collisions, an attacker can force the application to perform an excessive number of comparisons, consuming significant CPU resources and causing a DoS. The root cause is the predictable nature of the hash function, which allows for the creation of malicious input that exploits this weakness.
While no specific APTs are definitively linked to this specific CVE, the ease of exploitation and potential for widespread impact make it attractive to various threat actors. This type of DoS vulnerability is often used by financially motivated actors and script kiddies. CISA KEV: Not Listed
Monitor CPU usage of Ruby processes. Sudden spikes in CPU consumption, especially during periods of high traffic, can indicate a DoS attack.
Analyze application logs for unusual patterns, such as a large number of hash collisions or repeated requests with similar input.
Network traffic analysis: Look for a high volume of requests with potentially malicious payloads (e.g., long strings, repetitive data) that could be used to trigger hash collisions.
Implement rate limiting on input to prevent excessive requests.
Use intrusion detection systems (IDS) and intrusion prevention systems (IPS) with signatures designed to detect hash collision attacks.
Upgrade Ruby to version 1.8.7-p357 or later. This is the primary and most effective remediation.
Implement input validation to restrict the size and content of user-supplied data. This can limit the impact of crafted input.
Apply rate limiting to API endpoints and other input mechanisms to prevent a flood of requests.
Monitor application performance and resource usage to detect and respond to potential attacks.
Consider using a WAF (Web Application Firewall) to filter malicious requests.
If upgrading is not immediately possible, consider patching the Ruby source code to incorporate a more robust hash function or apply a backport of the fix.