CVE-2026-30957: @oneuptime/common Remote Code Execution Vulnerability

CRITICAL
Advisory Identifier: GHSA-jw8q-gjvg-8w4q
CVSS 9.9
CWE-749
Published
Advisory Summary

CVE-2026-30957 is a CRITICAL (CVSS 9.9) remote code execution vulnerability (CWE-749: Exposed Dangerous Method or Function) affecting @oneuptime/common libraries in the npm ecosystem. The issue involves oneuptime has synthetic monitor rce via exposed playwright browser object. Remediation is available by upgrading affected packages to version 10.0.21.

CVE-2026-30957 at a Glance

CVE Identifier CVE-2026-30957
GHSA Identifier GHSA-jw8q-gjvg-8w4q
Severity CRITICAL
CVSS v3.1 Base Score 9.9
CWE Classification CWE-749: Exposed Dangerous Method or Function
Affected Product @oneuptime/common
Package Ecosystem npm
Published Date
Last Updated

Security Impact

CVSS: 9.9

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H).

Attack Vector Network (AV:N)
Attack Complexity Low (AC:L)
Privileges Required Low (PR:L)
User Interaction None (UI:N)
Scope Changed (S:C)
Confidentiality High (C:H)
Integrity High (I:H)
Availability High (A:H)

How to Fix CVE-2026-30957

To remediate this vulnerability, upgrade all affected @oneuptime/common dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

@oneuptime/common fixed: 10.0.21
npm install @oneuptime/common@10.0.21
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

npm ls @oneuptime/common

How to Check if You Are Affected

To determine whether your Node.js application is affected by CVE-2026-30957, inspect your project dependencies using npm:

npm ls @oneuptime/common

Analyze the terminal output to locate any version of @oneuptime/common in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 10.0.21), your application is affected.

Note: The npm ls @oneuptime/common command inspects dependencies declared in your package.json and lockfile; it does not perform automated runtime dynamic scanning.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-749: Exposed Dangerous Method or Function, where the product provides an applications programming interface (api) or similar interface for interaction with external actors, but the interface includes a dangerous method or function that is not properly restricted. In @oneuptime/common, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

### 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: - `Monitor` access control: https://github.com/OneUptime/oneuptime/blob/707bfd62e721a2845ee05b87cb5d3c611bda2276/Common/Models/DatabaseModels/Monitor.ts#L45-L70 - `MonitorTest` access control: https://github.com/OneUptime/oneuptime/blob/707bfd62e721a2845ee05b87cb5d3c611bda2276/Common/Models/DatabaseModels/MonitorTest.ts#L27-L52 The dashboard exposes a Playwright code editor for Synthetic Monitors and allows a user to queue a test run: - Synthetic Monitor editor: https://github.com/OneUptime/oneuptime/blob/707bfd62e721a2845ee05b87cb5d3c611bda2276/App/FeatureSet/Dashboard/src/Components/Form/Monitor/MonitorStep.tsx#L260-L289 - `Test Monitor` flow: https://github.com/OneUptime/oneuptime/blob/707bfd62e721a2845ee05b87cb5d3c611bda2276/App/FeatureSet/Dashboard/src/Components/Form/Monitor/MonitorTest.tsx#L69-L83 For `MonitorType.SyntheticMonitor`, attacker-controlled `customCode` is passed into `SyntheticMonitor.execute(...)`: - https://github.com/OneUptime/oneuptime/blob/707bfd62e721a2845ee05b87cb5d3c611bda2276/Probe/Utils/Monitors/Monitor.ts#L323-L338 `SyntheticMonitor.execute(...)` then calls `VMRunner.runCodeInNodeVM(...)` and injects live Playwright objects into the VM context: - https://github.com/OneUptime/oneuptime/blob/707bfd62e721a2845ee05b87cb5d3c611bda2276/Probe/Utils/Monitors/MonitorTypes/SyntheticMonitor.ts#L156-L168 Relevant code path: ```ts 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`: - Blocked properties: https://github.com/OneUptime/oneuptime/blob/707bfd62e721a2845ee05b87cb5d3c611bda2276/Common/Server/Utils/VM/VMRunner.ts#L20-L25 - Real host `this` binding during method calls: https://github.com/OneUptime/oneuptime/blob/707bfd62e721a2845ee05b87cb5d3c611bda2276/Common/Server/Utils/VM/VMRunner.ts#L81-L103 - Additional context injection into the VM: https://github.com/OneUptime/oneuptime/blob/707bfd62e721a2845ee05b87cb5d3c611bda2276/Common/Server/Utils/VM/VMRunner.ts#L388-L395 Because of that, untrusted code can still use legitimate Playwright methods on the injected `browser` object. The probe pins Playwright `1.58.2`: - https://github.com/OneUptime/oneuptime/blob/707bfd62e721a2845ee05b87cb5d3c611bda2276/Probe/package-lock.json#L4438-L4459 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: ```javascript 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: - Monitor tests fetched by the probe: https://github.com/OneUptime/oneuptime/blob/707bfd62e721a2845ee05b87cb5d3c611bda2276/Probe/Jobs/Monitor/FetchMonitorTest.ts#L55-L85 - Scheduled monitor execution: https://github.com/OneUptime/oneuptime/blob/707bfd62e721a2845ee05b87cb5d3c611bda2276/Probe/Jobs/Monitor/FetchList.ts#L96-L126 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: ```javascript browser.browserType().launch({ executablePath: "/bin/sh", ignoreDefaultArgs: true, args: [ "-c", "id" ], timeout: 1000, }).catch((err) => { console.log(String(err)); }); return { data: { launched: true } }; ``` 5. Select one browser type, for example `Chromium`. 6. Select one screen type, for example `Desktop`. 7. Set retry count to `0`. 8. 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

CVE-2026-30957 Affected @oneuptime/common Versions

1 component(s)
Fixed Versions:
10.0.21
Product / Package Ecosystem Affected Versions Fixed Version
@oneuptime/common
npm
< 10.0.21
10.0.21

References

Frequently Asked Questions

What is CVE-2026-30957?
CVE-2026-30957 is a security vulnerability in @oneuptime/common involving OneUptime has Synthetic Monitor RCE via exposed Playwright browser object under CWE-749: Exposed Dangerous Method or Function.
Which @oneuptime/common versions are affected?
Affected versions include releases prior to 10.0.21 across affected packages: @oneuptime/common.
What version fixes CVE-2026-30957?
Upgrading to 10.0.21 (or the latest patched release for your respective branch) resolves the vulnerability.
Is @oneuptime/common affected?
Yes, @oneuptime/common is affected in releases prior to 10.0.21. Upgrade your dependency to 10.0.21 or later.
What is the CVSS score of CVE-2026-30957?
CVE-2026-30957 has a CVSS v3.1 base score of 9.9 (CRITICAL) with vector string CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H.
What CWE is associated with CVE-2026-30957?
CVE-2026-30957 is classified under CWE-749: Exposed Dangerous Method or Function (The product provides an Applications Programming Interface (API) or similar interface for interaction with external actors, but the interface includes a dangerous method or function that is not properly restricted.).
How can I check npm dependencies for CVE-2026-30957?
Run the dependency tree command: 'npm ls @oneuptime/common'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-jw8q-gjvg-8w4q",
  "modified" : "2026-03-10T18:45:14Z",
  "published" : "2026-03-10T01:12:59Z",
  "aliases" : [ "CVE-2026-30957" ],
  "summary" : "OneUptime has Synthetic Monitor RCE via exposed Playwright browser object",
  "details" : "### Summary\n\nOneUptime Synthetic Monitors allow a low-privileged authenticated project user to execute arbitrary commands on the `oneuptime-probe` server/container.\n\nThe 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.\n\nThis is a server-side remote code execution issue. It does not require a separate `vm` sandbox escape.\n\n## Details\n\nA normal project member can create or edit monitors and monitor tests:\n\n- `Monitor` access control: https://github.com/OneUptime/oneuptime/blob/707bfd62e721a2845ee05b87cb5d3c611bda2276/Common/Models/DatabaseModels/Monitor.ts#L45-L70\n- `MonitorTest` access control: https://github.com/OneUptime/oneuptime/blob/707bfd62e721a2845ee05b87cb5d3c611bda2276/Common/Models/DatabaseModels/MonitorTest.ts#L27-L52\n\nThe dashboard exposes a Playwright code editor for Synthetic Monitors and allows a user to queue a test run:\n\n- Synthetic Monitor editor: https://github.com/OneUptime/oneuptime/blob/707bfd62e721a2845ee05b87cb5d3c611bda2276/App/FeatureSet/Dashboard/src/Components/Form/Monitor/MonitorStep.tsx#L260-L289\n- `Test Monitor` flow: https://github.com/OneUptime/oneuptime/blob/707bfd62e721a2845ee05b87cb5d3c611bda2276/App/FeatureSet/Dashboard/src/Components/Form/Monitor/MonitorTest.tsx#L69-L83\n\nFor `MonitorType.SyntheticMonitor`, attacker-controlled `customCode` is passed into `SyntheticMonitor.execute(...)`:\n\n- https://github.com/OneUptime/oneuptime/blob/707bfd62e721a2845ee05b87cb5d3c611bda2276/Probe/Utils/Monitors/Monitor.ts#L323-L338\n\n`SyntheticMonitor.execute(...)` then calls `VMRunner.runCodeInNodeVM(...)` and injects live Playwright objects into the VM context:\n\n- https://github.com/OneUptime/oneuptime/blob/707bfd62e721a2845ee05b87cb5d3c611bda2276/Probe/Utils/Monitors/MonitorTypes/SyntheticMonitor.ts#L156-L168\n\nRelevant code path:\n\n```ts\nresult = await VMRunner.runCodeInNodeVM({\n  code: options.script,\n  options: {\n    timeout: PROBE_SYNTHETIC_MONITOR_SCRIPT_TIMEOUT_IN_MS,\n    args: {},\n    context: {\n      browser: browserSession.browser,\n      page: browserSession.page,\n      screenSizeType: options.screenSizeType,\n      browserType: options.browserType,\n    },\n  },\n});\n```\n\n`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`:\n\n- Blocked properties: https://github.com/OneUptime/oneuptime/blob/707bfd62e721a2845ee05b87cb5d3c611bda2276/Common/Server/Utils/VM/VMRunner.ts#L20-L25\n- Real host `this` binding during method calls: https://github.com/OneUptime/oneuptime/blob/707bfd62e721a2845ee05b87cb5d3c611bda2276/Common/Server/Utils/VM/VMRunner.ts#L81-L103\n- Additional context injection into the VM: https://github.com/OneUptime/oneuptime/blob/707bfd62e721a2845ee05b87cb5d3c611bda2276/Common/Server/Utils/VM/VMRunner.ts#L388-L395\n\nBecause of that, untrusted code can still use legitimate Playwright methods on the injected `browser` object.\n\nThe probe pins Playwright `1.58.2`:\n\n- https://github.com/OneUptime/oneuptime/blob/707bfd62e721a2845ee05b87cb5d3c611bda2276/Probe/package-lock.json#L4438-L4459\n\nIn 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.\n\nAs a result, a malicious Synthetic Monitor can do this from inside the sandboxed script:\n\n```javascript\nbrowser.browserType().launch({\n  executablePath: \"/bin/sh\",\n  ignoreDefaultArgs: true,\n  args: [\"-c\", \"id\"],\n});\n```\n\nEven if Playwright later throws because the spawned process is not a real browser, the command has already executed.\n\nThis execution path is reachable through both one-shot monitor testing and normal scheduled monitor execution:\n\n- Monitor tests fetched by the probe: https://github.com/OneUptime/oneuptime/blob/707bfd62e721a2845ee05b87cb5d3c611bda2276/Probe/Jobs/Monitor/FetchMonitorTest.ts#L55-L85\n- Scheduled monitor execution: https://github.com/OneUptime/oneuptime/blob/707bfd62e721a2845ee05b87cb5d3c611bda2276/Probe/Jobs/Monitor/FetchList.ts#L96-L126\n\nThis 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.\n\n### PoC\n\n1. Log in to the dashboard as a regular project member.\n2. Go to `Monitors` -> `Create New Monitor`.\n3. Select `Synthetic Monitor`.\n4. In the Playwright code field, paste:\n\n```javascript\n browser.browserType().launch({\n    executablePath: \"/bin/sh\",\n    ignoreDefaultArgs: true,\n    args: [\n      \"-c\",\n      \"id\"\n    ],\n    timeout: 1000,\n  }).catch((err) => {\n    console.log(String(err));\n  });\n\n  return {\n    data: {\n      launched: true\n    }\n  };\n```\n\n5. Select one browser type, for example `Chromium`.\n6. Select one screen type, for example `Desktop`.\n7. Set retry count to `0`.\n8. Click `Test Monitor` and choose any probe.\n\nExpected result:\n\n- the monitor execution succeeded and in the Show More Details the command output is shown.\n<img width=\"1537\" height=\"220\" alt=\"image\" src=\"https://github.com/user-attachments/assets/4fa5b458-cae9-4ec8-add0-bfc288ee7568\" />\n\n### Impact\nThis is a server-side Remote Code Execution issue affecting the probe component.\n\nWho is impacted:\n\n- any OneUptime deployment where an attacker can obtain ordinary project membership\n- environments where the probe has access to internal services, secrets, Kubernetes metadata, database credentials, proxy credentials, or other cluster-local trust relationships",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "npm",
      "name" : "@oneuptime/common"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "10.0.21"
      } ]
    } ]
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/OneUptime/oneuptime/security/advisories/GHSA-jw8q-gjvg-8w4q"
  }, {
    "type" : "ADVISORY",
    "url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-30957"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/OneUptime/oneuptime"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/OneUptime/oneuptime/releases/tag/10.0.21"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-749" ],
    "severity" : "CRITICAL",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-03-10T01:12:59Z",
    "nvd_published_at" : "2026-03-10T18:18:54Z"
  }
}