# kobako Sandbox Escape: guest eval reaches host RCE via method_missing → public_send (any bound Service)

Kobako's wasm transport dispatcher passed guest method names to public_send, letting a sandboxed mruby script call send(:eval) on any bound Service for host RCE.

- Payout: Research
- Severity: critical
- Program: Kobako
- Found by: alhafoudh
- Disclosed: 2026-08-18
- CVE: CVE-2026-55107
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-7pwq-q9jf-539h
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-7pwq-q9jf-539h
- Tags: area:oss domain:oss impact:internal-access impact:rce kind:research platform:ghsa sev:critical tech:ruby technique:source-review vuln:access-control vuln:rce vuln:sandbox-escape

**Target:** Ruby gem wasm/mruby sandbox transport dispatcher
**Root cause:** The transport dispatcher forwarded the guest-supplied method name directly to `Object#public_send` on the bound Service object without restricting dispatch to the object's own methods, exposing ambient reflection like `send`.
**Steps:**
1. Host binds a Service object into the sandbox; guest scripts call it across the wasm boundary via the dispatcher.
2. Guest sends a dispatch request with `method = "send"` and `args = [:eval, "<ruby>"]`.
3. Dispatcher executes `target.public_send(:send, :eval, "<ruby>")`, i.e. `target.send(:eval, "<ruby>")`.
4. Attacker-controlled Ruby runs in the host process.
**How found:** Noticed the dispatcher passed guest-controlled method names straight to `public_send`, then reasoned that public_send reaches Ruby's ambient reflection surface, pivoting through public `send` into private Kernel methods like `eval`.
**Exploitation:** Any bound Service object suffices: a single guest dispatch call `Service.send(:eval, "<arbitrary host ruby>")` executes in the host process, allowing reads/modification of host state and process spawning.
**Insight:** When a sandbox dispatches guest-chosen method names onto host objects, `public_send` is not a safe allowlist: `send`, `__send__`, `instance_eval`, `method`, `instance_variable_get` are all public and owned by Kernel/Object, so filter by resolved method owner, not by visibility.

## Proof of concept (copied exactly from the original report)

**Guest call evaluating arbitrary host Ruby via send**

```
Service.send(:eval, "<arbitrary host ruby>")
```

