Jun 3, 2026·6 min read·104 visits
Unauthenticated remote code execution vulnerability in browserstack-runner <= 0.9.5 via a sandbox escape in the /_log HTTP handler.
An unauthenticated remote code execution (RCE) vulnerability exists in the browserstack-runner npm package (versions up to and including 0.9.5). The flaw lies in the /_log HTTP endpoint handler, which evaluates user-supplied input within a non-secure Node.js VM context combined with dynamic eval() execution. Network-adjacent attackers can exploit this behavior to escape the sandbox and execute arbitrary system commands on the host machine.
The npm package browserstack-runner is designed to facilitate automated cross-browser testing by establishing a local HTTP server that communicates test status and logs back to the testing execution framework. By default, this HTTP daemon binds to all network interfaces (0.0.0.0) on port 8888. This configuration exposes the internal API endpoint handlers directly to any system residing on the same local area network or adjacent network segment.
While several critical endpoints within the runner server enforce authentication checks (such as verifying worker session UUIDs), the /_log HTTP handler lacks any form of access control or identity validation. This omission permits unauthenticated users on the adjacent network to interact directly with the endpoint.
When a POST request is made to /_log, the server accepts a JSON-formatted request body containing a sequence of log arguments. The server processes these arguments using dangerous evaluation primitives, leading directly to a code execution vector. The combination of unrestricted network exposure and insecure processing mechanics forms the basis of the security boundary failure.
The root cause of CVE-2026-49143 lies in the execution of unsanitized input within Node.js's native vm module, augmented by a nested call to eval(). Standard Node.js vm contexts do not establish a secure isolation boundary. The Node.js documentation explicitly states that the vm module is not a security mechanism and must not be used to run untrusted code.
The vulnerability is located in lib/server.js (lines 491–515). When a request is received on the /_log route, the application extracts the user-supplied query.arguments array and places it directly into the execution context. The application then attempts to evaluate each entry within a dynamic execution string mapped inside the sandbox.
Sandbox isolation is bypassed through two primary mechanisms. First, the application passes a host-context function reference (util.format) into the context configuration. Because this function originates from outside the sandbox, its constructor property references the global Function constructor of the parent Node.js process. Second, even in the absence of explicit function leakage, JavaScript prototype inheritance allows context navigation. An attacker can access the prototype of standard objects within the sandbox, such as this.constructor.constructor, to retrieve the host-level Function constructor. This constructor can then instantiate and execute arbitrary code in the host's main execution loop.
The vulnerable code path is implemented in lib/server.js as follows:
// lib/server.js - Lines 504-510 (Vulnerable Implementation)
var context = { input: query.arguments, format: util.format, output: '' };
var tryEvalOrString = 'function (arg) { try { return eval(\'o = \' + arg); } catch (e) { return arg; } }';
vm.runInNewContext('output = format.apply(null, input.map(' + tryEvalOrString + '));', context);The input array (query.arguments) maps directly to the input property inside the VM context. The string tryEvalOrString represents a JavaScript function that performs direct execution using eval('o = ' + arg). When vm.runInNewContext executes, it evaluates this mapping function over every index in the user-supplied input.
Because the format property points to the host's util.format library, the context is contaminated with a direct pathway back to the Node.js root runtime. The system processes the input inside the helper function via string concatenation in eval(), executing any arbitrary JavaScript statements embedded inside the query.arguments strings.
There is no validation or sanitization applied to query.arguments before it enters the tryEvalOrString execution loop. As a result, the sandbox environment is neutralized, permitting direct interaction with host system binaries.
Exploitation of CVE-2026-49143 requires three conditions: network access to the port on which browserstack-runner is listening, the absence of network firewalls blocking incoming connections, and an active runner server instance.
An attacker constructs a JSON payload containing an injection string targeting the array index of the arguments key. The objective of the injection is to escape the local scope, navigate to the parent constructor, retrieve the process global object, and invoke the operating system shell using the child_process module.
The payload retrieves the host context via the prototype constructor hierarchy. The string this.constructor.constructor("return process")() resolves to the master Node.js process object. From there, the attacker chains a call to require('child_process') and executes command-line binaries via synchronous execution methods.
curl -s http://<target_ip>:8888/_log \
-H "Content-Type: application/json" \
-d '{"arguments":["this.constructor.constructor(\"return process.mainModule.require(\\\`child_process\\\`).execSync(\\\`id\\\`).toString()\")()"]}'When the runner server parses this payload, it executes the payload within the nested helper context. The server subsequently returns a response or prints the execution results directly to the process log buffer, exposing the output of the local command execution back to the attacker.
The security impact of CVE-2026-49143 is rated high, with a CVSS v3.1 base score of 8.8 (CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H). The vulnerability allows complete compromise of the workstation or build server executing the runner.
Because developers and continuous integration (CI) pipelines frequently run automated testing processes with high privileges, exploiting this vulnerability provides access to sensitive development environments. This includes access to environment variables, local source code, configuration files, cloud credentials, and private SSH/API keys.
The execution context inherits the user permissions of the shell running the Node.js application. If the developer runs the test suite with administrative or root privileges, the compromised environment inherits those credentials. This can lead to system-wide compromise or lateral movement within local corporate networks.
The recommended solution to resolve CVE-2026-49143 is to refactor the logging execution mechanism to eliminate dynamic interpretation engines. The system must not use eval() or vm.runInNewContext() to process logging strings.
To remediate this behavior locally, replace the sandbox processing chain with safe formatting and serialization functions. Converting log arguments directly to string representations prevents execution commands from being interpreted as program logic:
// Safe logging replacement
var safeOutput = query.arguments.map(function(arg) {
return typeof arg === 'object' ? JSON.stringify(arg) : String(arg);
}).join(' ');Additionally, restrict the network exposure of the HTTP daemon. Configure the server application to bind exclusively to 127.0.0.1 instead of 0.0.0.0 in lib/server.js. This binding modification restricts access to the local machine, preventing exploitation attempts from adjacent hosts over local networks or shared Wi-Fi connections.
CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
browserstack-runner browserstack | <= 0.9.5 | - |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-94: Improper Control of Generation of Code ('Code Injection') |
| Attack Vector | Adjacent Network |
| CVSS v3.1 Score | 8.8 |
| CVSS v4.0 Score | 8.7 |
| Exploit Status | poc |
| KEV Status | Not Listed |
| Impact | High (Complete Confidentiality, Integrity, and Availability Loss) |
The software constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes the input before executing it.
A remote code execution vulnerability exists in Microsoft .NET due to untrusted data deserialization within the PresentationCore component. The flaw stems from implicit auto-conversion flags during clipboard data retrieval operations.
An out-of-bounds write vulnerability in Microsoft .NET Framework, .NET runtime, and Visual Studio allows unauthenticated remote attackers to execute arbitrary code via crafted pixel-shader bytecode or auto-converted clipboard payloads.
ASP.NET Core contains a thread deadlock vulnerability (CWE-833) that allows an unauthenticated remote attacker to cause a denial of service over the network by exhausting server thread pool resources.
CVE-2026-70035 is a high-severity Remote Code Execution (RCE) vulnerability in Microsoft .NET Framework, .NET runtime, and Visual Studio caused by improper handling during the deserialization of untrusted data (CWE-502). An unauthenticated attacker can execute arbitrary code within the context of the affected process by delivering a crafted serialized payload.
An elevation of privilege vulnerability exists in ASP.NET Core and Microsoft Visual Studio due to improper synchronization during concurrent thread execution. Authenticated remote attackers with low privileges can exploit a timing window to manipulate shared resources and assume higher-level execution contexts.
A path traversal vulnerability (CWE-22) in Contao CMS allows unauthenticated remote attackers to bypass directory boundary restrictions in ImagesController and access files within the project directory.