# browserstack-runner vulnerable to Remote Code Execution via vm sandbox escape in _log HTTP handler

Unauthenticated /_log handler in browserstack-runner passes request JSON to vm.runInNewContext with eval, escaping the sandbox to run host commands.

- Payout: Research
- Severity: high
- Program: browserstack-runner
- Found by (vendor credit): Christ Bouchuen
- Found by: Christbowel
- Disclosed: 2026-06-03
- CVE: CVE-2026-49143
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-6vr3-7wcx-v5g5
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-6vr3-7wcx-v5g5
- Tags: area:web domain:oss domain:web impact:rce kind:research platform:ghsa sev:high tech:nodejs technique:source-review vuln:auth-bypass vuln:command-injection vuln:rce

**Target:** HTTP /_log endpoint on port 8888 (Node.js vm sandbox)
**Root cause:** The /_log handler feeds unauthenticated request arguments into vm.runInNewContext with an eval-based mapper, and the context leaks host Function via util.format, allowing this.constructor.constructor to reach process.
**Steps:**
1. Start runner: `node bin/runner.js` with a browserstack.json and t.html; server listens on 0.0.0.0:8888
2. POST to `/_log` with JSON body `{"arguments":["this.constructor.constructor(\"return process.mainModule.require(`child_process`).execSync(`id`).toString()\")()"]}`
3. Handler builds context `{input: query.arguments, format: util.format, output: ''}` and runs `vm.runInNewContext('output = format.apply(null, input.map(' + tryEvalOrString + '));', context)`
4. eval executes the payload; host Function constructor escapes sandbox and execSync runs `id`, output printed in runner console
**How found:** Code review of lib/server.js: noticed _log lacked the UUID auth used by _progress/_report, and that the vm context exposed util.format (a host Function), making the sandbox escapable.
**Exploitation:** Attacker on the same network sends one unauthenticated POST to port 8888 during a test run (1-15 min window); the eval'd argument escapes the vm context via this.constructor.constructor and executes arbitrary OS commands as the developer, with access to BrowserStack access key env vars.
**Insight:** When a vm.runInNewContext context object includes any host-realm function (like util.format), `this.constructor.constructor` reaches the real Function constructor and escapes; also compare auth checks across sibling HTTP handlers to spot the unguarded one.

