CVE-2026-30957: OneUptime Synthetic Monitor RCE via exposed Playwright browser object

Published Mar 10, 2026
·
Updated

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: PROBESYNTHETICMONITORSCRIPTTIMEOUTINMS, 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

Other sources

OneUptime is a solution for monitoring and managing online services. Prior to 10.0.21, 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. This vulnerability is fixed in 10.0.21.

— MITRE

Affected Software

2 affected componentsFixes available
npm/@oneuptime/common<10.0.21
10.0.21
Hackerbay Oneuptime<10.0.21

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade npm/@oneuptime/common to a version that resolves this vulnerability.

    Fixed in 10.0.21
  2. Upgrade

    Upgrade OneUptime to a version that resolves this vulnerability.

    Fixed in 10.0.21

Event History

Mar 10, 2026
Advisory Published
via GitHub·01:12 AM
Data Sourced
via GitHub·01:12 AM
DescriptionSeverityWeaknessAffected Software
CVE Published
via MITRE·04:58 PM
Data Sourced
via MITRE·04:58 PM
DescriptionSeverityWeakness
Data Sourced
via NVD·06:18 PM
DescriptionSeverityWeaknessAffected Software
Feb 17, 58167
Event
via FIRST·06:10 PM

Frequently Asked Questions

1

What is the severity of CVE-2026-30957?

CVE-2026-30957 is considered a critical vulnerability due to its potential to allow arbitrary command execution.

2

How do I fix CVE-2026-30957?

To mitigate CVE-2026-30957, upgrade the affected package to version 10.0.21 or later.

3

Who is affected by CVE-2026-30957?

The vulnerability affects low-privileged authenticated project users of OneUptime Synthetic Monitors.

4

What is the impact of CVE-2026-30957?

CVE-2026-30957 allows unauthorized command execution on the oneuptime-probe server/container, compromising the security of the system.

5

Is there a workaround for CVE-2026-30957?

Currently, the recommended action for CVE-2026-30957 is to upgrade to a non-vulnerable version, as no direct workaround is provided.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203