Critical Deserialization Vulnerability in Ruby Background Workers Poses Severe Security Risks
A significant Remote Code Execution (RCE) vulnerability has been discovered in a Ruby-based background job processing system, stemming from unsafe JSON deserialization practices. This flaw enables attackers to transform untrusted input into executable objects, potentially leading to full system compromise.
Understanding the Vulnerability
The core issue lies in the application’s reliance on the `Oj` gem for JSON processing. When untrusted input is deserialized using `Oj.load`, it reconstructs fully functional Ruby objects, complete with methods and system access. This process bridges the gap between data and code, creating a pathway for attackers to execute arbitrary commands within the background worker context.
Mechanics of Exploitation
The vulnerability manifests in the application’s background job pattern, where user-controlled input is stored as a JSON payload and later deserialized by a background worker. The critical line of code, `data = Oj.load(job.payload)`, performs object deserialization instead of simple JSON parsing.
Security researchers have highlighted that `Oj.load` can reconstruct objects using special JSON directives, such as `{^o: ClassName}`. This allows an attacker to allocate a class instance, inject variables, and return a functional object.
Risk Assessment
The exploitation chain is fully deterministic and requires no injection tricks. The payload is stored, reconstructed, and then executed, allowing arbitrary shell commands to be run. This enables unauthenticated attackers to gain control over background workers, often resulting in complete system compromise.
Mitigation Strategies
To mitigate this vulnerability, developers must treat serialized input as hostile by default. It is recommended to use `Oj.safe_load` or strict parsing modes to ensure data is handled safely. Additionally, dynamic dispatch should be replaced with explicit job handling, and execution of operating system commands with user-controlled arguments should be avoided entirely.