Ruby Workers Face Critical RCE from Unsafe Oj Deserialization


NullSecurityX disclosed deterministic RCE in Ruby background workers using Oj.load deserialization. Unauthenticated attackers craft JSON payloads triggering arbitrary shell commands via Node class. No gadget chains required; single line data = Oj.load(job.payload) enables full compromise.

Applications store user-controlled JSON in job queues for async processing. Background workers deserialize payloads reconstructing executable Ruby objects. Oj gem object mode bridges data-to-code boundary silently.

{“^o”:”Node”} JSON directive instantiates Node class with injected methods. Capability-based dispatch calls run_find exposing Open3.capture3 execution. Shell commands pass as find arguments achieving RCE.

Attack chain spans web request to worker execution without authentication. Dynamic respond_to? routing authorizes malicious objects automatically. Design flaw assumes deserialized data remains inert.

find / -maxdepth 0 -exec sh -c ‘command’ pattern executes payloads reliably. No memory corruption or obscure conditions needed. Worker context grants filesystem, network, persistence access immediately.

Enterprise Ruby deployments face highest exposure from SaaS patterns. Sidekiq, Resque, GoodJobs patterns require immediate audits. Deserialization represents persistent blindspot in modern web architectures.

Ruby background job processing system (source : NullSecurityX)

Vulnerability Mechanics Table

ComponentRiskAttack Vector
Oj.loadCriticalObject reconstruction
Node.run_findCriticalOpen3.capture3 abuse
respond_to? dispatchHighUnauthorized method calls
Job payload storageHighUser-controlled JSON

Attack Indicators

TypeIndicator
JSON Pattern{“^o”:”Node”} object tag
Process Executionfind / -maxdepth 0 -exec sh
Worker ContextOpen3.capture3 from jobs
Suspicious MethodsDynamic dispatch calls

Oj.safe_load enforces strict parsing blocking object creation. Explicit job handlers replace dynamic dispatch entirely.

Remediation Steps

  • Replace Oj.load with Oj.safe_load everywhere
  • Implement explicit job class mapping
  • Remove Open3.capture3 from deserialized contexts
  • Audit all background worker payloads
  • Deploy WAF rules blocking ^o JSON patterns
  • Monitor find command abuse from workers

Production Rails, Sinatra apps require comprehensive deserialization scans. Container escapes possible from compromised workers. Rapid patching prevents widespread exploitation campaigns.

FAQ

What triggers Ruby worker RCE vulnerability?

Oj.load deserializing untrusted JSON payloads containing {“^o”:”Node”}.

Which gem creates the deserialization risk?

Oj gem object mode reconstructing executable Ruby objects.

Attack requirements for exploitation?

Unauthenticated JSON payload storage in background job queue.

Primary execution vector used?

Node.run_find method abusing Open3.capture3 shell calls.

Recommended immediate fix?

Switch to Oj.safe_load strict parsing mode.

Affected Ruby job frameworks?

Sidekiq, Resque, GoodJobs, custom implementations.

Readers help support VPNCentral. We may get a commission if you buy through our links. Tooltip Icon

Read our disclosure page to find out how can you help VPNCentral sustain the editorial team Read more

User forum

0 messages