Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
📦
📦 npm
Not in CISA KEV
CRITICAL severity

GHSA-jw8q-gjvg-8w4q

CRITICAL

GHSA-jw8q-gjvg-8w4q is a critical-severity (CVSS 9.9) CWE-749 vulnerability in @oneuptime/common. O3 Security confirms whether GHSA-jw8q-gjvg-8w4q is actually reachable in your code before you act, and blocks exploitation at runtime until you patch.

OneUptime has Synthetic Monitor RCE via exposed Playwright browser object

Also known asCVE-2026-30957
Published
Mar 10, 2026
Updated
Mar 10, 2026
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Mar 10, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Real-World Exposure

1 pkg affected

How broadly this vulnerability is actually deployed: weekly install volume shows current usage, a proxy for how much of the ecosystem is exposed.

@oneuptime/commonnpm
3Kdownloads / week

Description

Summary

OneUptime Synthetic Monitors allow a low-privileged authenticated project user to execute arbitrary commands on the oneuptime-probe server/container.

The root cause is that untrusted Synthetic Monitor code is executed inside Node's vm while live host-realm Playwright browser and page objects are exposed to it. A malicious user can call Playwright APIs on the injected browser object and cause the probe to spawn an attacker-controlled executable.

This is a server-side remote code execution issue. It does not require a separate vm sandbox escape.

Details

A normal project member can create or edit monitors and monitor tests:

The dashboard exposes a Playwright code editor for Synthetic Monitors and allows a user to queue a test run:

For MonitorType.SyntheticMonitor, attacker-controlled customCode is passed into SyntheticMonitor.execute(...):

SyntheticMonitor.execute(...) then calls VMRunner.runCodeInNodeVM(...) and injects live Playwright objects into the VM context:

Relevant code path:

result = await VMRunner.runCodeInNodeVM({
  code: options.script,
  options: {
    timeout: PROBE_SYNTHETIC_MONITOR_SCRIPT_TIMEOUT_IN_MS,
    args: {},
    context: {
      browser: browserSession.browser,
      page: browserSession.page,
      screenSizeType: options.screenSizeType,
      browserType: options.browserType,
    },
  },
});

VMRunner.runCodeInNodeVM(...) wraps host objects in proxies, but it still forwards normal method calls with the real host this binding. It only blocks a few property names such as constructor, __proto__, prototype, and mainModule:

Because of that, untrusted code can still use legitimate Playwright methods on the injected browser object.

The probe pins Playwright 1.58.2:

In that version, Browser.browserType() returns a BrowserType object, and BrowserType.launch() accepts attacker-controlled executablePath, ignoreDefaultArgs, and args. Playwright then passes those values into a child-process spawn path.

As a result, a malicious Synthetic Monitor can do this from inside the sandboxed script:

browser.browserType().launch({
  executablePath: "/bin/sh",
  ignoreDefaultArgs: true,
  args: ["-c", "id"],
});

Even if Playwright later throws because the spawned process is not a real browser, the command has already executed.

This execution path is reachable through both one-shot monitor testing and normal scheduled monitor execution:

This appears distinct from prior node:vm breakout issues because the exploit does not need to recover process from the VM. The dangerous capability is already exposed by design through the injected Playwright object.

PoC

  1. Log in to the dashboard as a regular project member.
  2. Go to Monitors -> Create New Monitor.
  3. Select Synthetic Monitor.
  4. In the Playwright code field, paste:
 browser.browserType().launch({
    executablePath: "/bin/sh",
    ignoreDefaultArgs: true,
    args: [
      "-c",
      "id"
    ],
    timeout: 1000,
  }).catch((err) => {
    console.log(String(err));
  });

  return {
    data: {
      launched: true
    }
  };
  1. Select one browser type, for example Chromium.
  2. Select one screen type, for example Desktop.
  3. Set retry count to 0.
  4. Click Test Monitor and choose any probe.

Expected result:

  • the monitor execution succeeded and in the Show More Details the command output is shown. <img width="1537" height="220" alt="image" src="https://github.com/user-attachments/assets/4fa5b458-cae9-4ec8-add0-bfc288ee7568" />

Impact

This is a server-side Remote Code Execution issue affecting the probe component.

Who is impacted:

  • any OneUptime deployment where an attacker can obtain ordinary project membership
  • environments where the probe has access to internal services, secrets, Kubernetes metadata, database credentials, proxy credentials, or other cluster-local trust relationships

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
📦npm@oneuptime/commonall versions10.0.21

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for @oneuptime/common. O3's reachability analysis confirms whether the vulnerable code path is actually invoked in your application, so you act on real exposure instead of every transitive match.

  2. Fix

    Update @oneuptime/common to 10.0.21 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-jw8q-gjvg-8w4q is resolved across your whole dependency graph.

  3. Workarounds

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

  4. How O3 protects you

    O3 pinpoints whether GHSA-jw8q-gjvg-8w4q is reachable in your code and exactly where to fix it, then blocks exploitation in production at runtime until the patched version is deployed.

Tailored to GHSA-jw8q-gjvg-8w4q. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.

Frequently Asked Questions

### Summary OneUptime Synthetic Monitors allow a low-privileged authenticated project user to execute arbitrary commands on the `oneuptime-probe` server/container. The root cause is that untrusted Synthetic Monitor code is executed inside Node's `vm` while live host-realm Playwright `browser` and `page` objects are exposed to it. A malicious user can call Playwright APIs on the injected `browser` object and cause the probe to spawn an attacker-controlled executable. This is a server-side remote code execution issue. It does not require a separate `vm` sandbox escape. ## Details A normal p
O3 Security · Impact-Aware SCA

Is GHSA-jw8q-gjvg-8w4q in your dependencies?

O3 detects GHSA-jw8q-gjvg-8w4q across npm dependencies and uses function-level reachability to confirm whether the vulnerable code path is actually reachable — not just present. No false positives.

GHSA-jw8q-gjvg-8w4q: @oneuptime/common… | O3 Security