Skip to content

CVE-2026-66013: Verified Reproduction

CVE-2026-66013: OpenRemote console registration authentication bypass via known asset identifier

CVE-2026-66013 is verified against openremote · github. Affected versions: OpenRemote <= 1.26.1; the advisory says the flaw was directly validated on 1.25.0. Fixed in OpenRemote 1.26.2 and later. Vulnerability class: Auth Bypass. This critical reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00300.

REPRO-2026-00300 openremote · github Auth Bypass Jul 27, 2026 CVE entry ↗ .txt
Severity
CRITICAL
Confidence
HIGH
Reproduced in
35m 36s
Tool calls
209
Spend
$13.73
01 · Overview

What Is CVE-2026-66013?

CVE-2026-66013 is a critical-severity Auth Bypass vulnerability affecting openremote OpenRemote <= 1.26.1; the advisory says the flaw was directly validated on 1.25.0.. Pruva has independently reproduced it and publishes a verified, runnable proof-of-concept (reproduction REPRO-2026-00300).

02 · Severity & CVSS

CVE-2026-66013 Severity

CVE-2026-66013 is rated critical severity.

CRITICAL threat level
Weakness CWE-639 — Authorization Bypass Through User-Controlled Key

Critical — the most severe class — typically remotely exploitable with severe impact. Treat as an emergency.

03 · Affected Versions

Affected openremote Versions

openremote · github versions OpenRemote <= 1.26.1; the advisory says the flaw was directly validated on 1.25.0. are affected.

How to Reproduce CVE-2026-66013

$ pruva-verify REPRO-2026-00300
or curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00300/artifacts/bundle/repro/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh
Run in a VM or disposable container. This exploits a real vulnerability.
06 · Proof of Reproduction

Proof of Reproduction for CVE-2026-66013

Authorization bypass — reproduced
  • reached the target end-to-end
  • full exploit chain demonstrated
  • on the real production code path
  • high confidence
  • the upstream fix blocks the same trigger
Trigger

Unauthenticated JSON registration body containing a known existing console asset ID, replacement console metadata, and replacement push provider token

Attack chain
  1. POST /api/master/console/register
  2. ConsoleResourceImpl.register()
  3. AssetStorageService.merge(existing ConsoleAsset)
How the agent worked 420 events · 209 tool calls · 36 min
36 minDuration
209Tool calls
70Reasoning steps
420Events
18Dead-ends
Agent activity over 36 min
Policy
1
Support
30
Repro
350
Judge
34
Verify
1
0:0035:36

Root Cause and Exploit Chain for CVE-2026-66013

Versions: component: OpenRemote Manager console registration API, specifically ConsoleResourceImpl.register() behind POST /api/{realm}/console/register.Fixed: 1.26.2, vendor image source commit 87845b5d9bccc74ba144e5879994780b92f69089.

OpenRemote 1.25.0 (and, per the advisory, all releases through 1.26.1) exposes POST /api/{realm}/console/register as an anonymous console-registration endpoint. The vulnerable implementation interprets a client-supplied id as both an object reference and sufficient authority to update that object. An unauthenticated caller who knows an existing ConsoleAsset ID can therefore load that asset globally, replace its console metadata and provider map—including the push-notification token—and persist the change without proving authentication, ownership, or realm membership. Current-runtime testing through the real OpenRemote HTTP service confirmed the flaw twice and showed OpenRemote 1.26.2 rejecting the same procedure twice with HTTP 403.

  • Affected component: OpenRemote Manager console registration API, specifically ConsoleResourceImpl.register() behind POST /api/{realm}/console/register.
  • Affected versions: Advisory range <= 1.26.1; the runtime proof uses the vendor openremote/manager:1.25.0 image (source commit 0ed159ba423de28896ab77a07427cdc32ed0712a).
  • Fixed version: 1.26.2, vendor image source commit 87845b5d9bccc74ba144e5879994780b92f69089.
  • Risk: Critical authorization bypass / insecure direct object reference (CWE-639, also consistent with CWE-862). Network access and knowledge of a victim console asset ID are sufficient; no bearer token or user session is needed.
  • Consequences: Persistent replacement of console name, version, platform, and provider data. In particular, replacing the push token can redirect console notifications to attacker-controlled routing data or deny delivery by installing an invalid token. The reproduced victims were created by a real authenticated owner and retained one owner link while anonymous requests modified their state.

Impact Parity

  • Disclosed/claimed maximum impact: Unauthenticated remote authorization bypass allowing overwrite of an existing console's push token and metadata.
  • Reproduced impact: Two independent unauthenticated API requests on OpenRemote 1.25.0 returned HTTP 200 for existing, owner-linked console IDs and persisted attacker-selected console names and push tokens. SQL evidence confirms each asset still had one owner link. The same procedure against 1.26.2 returned HTTP 403 and preserved original values in two attempts.
  • Parity: full
  • Not demonstrated: The proof intentionally does not contact Firebase or send a real push notification. It proves the persistent routing-token overwrite that enables notification redirection or denial, not delivery through a third-party push provider. No broader account login bypass or code execution was claimed or attempted.

Root Cause

The endpoint is deliberately public so a new console can register anonymously. In 1.25.0, however, ConsoleResourceImpl.register() also accepts a caller-supplied id for updates:

  1. Lines 83–90 read the submitted ID and perform assetStorageService.find(id, true), which globally loads the existing asset.
  2. The only check is that the object is a ConsoleAsset; there is no authentication, ownership-link, or realm equality check.
  3. Lines 106–125 copy attacker-controlled name, provider map, version, and platform into that existing asset.
  4. Lines 128–130 call assetStorageService.merge(consoleAsset), persisting the changes.
  5. Ownership handling at lines 133–140 is guarded by isAuthenticated() and therefore does not restrict the anonymous update path.

The public API declaration itself says an ID means “update” while also stating that the endpoint allows anonymous registration. The implementation failed to distinguish anonymous creation from mutation of existing server-side state. Possession of an object identifier was incorrectly treated as write authority.

OpenRemote 1.26.2 fixes this in ConsoleResourceImpl by tracking existingConsole, requiring the loaded asset realm to match, rejecting anonymous existing-console updates with HTTP 403, and requiring an authenticated user's existing asset link before mutation. It also rejects a supplied ID that does not exist. The fixed release commit is 87845b5d9bccc74ba144e5879994780b92f69089.

Reproduction Steps

  1. Run bundle/repro/reproduction_steps.sh from any directory (optionally set PRUVA_ROOT to the bundle path).

  2. The script:

    • Resolves the prepared project cache from bundle/project_cache_context.json and verifies the 1.25.0 and 1.26.2 source commits.
    • Installs its required Java/PostgreSQL/PostGIS/TimescaleDB/OCI tools.
    • Downloads and unpacks exact vendor OCI image bytes for OpenRemote Manager 1.25.0, OpenRemote Manager 1.26.2, and OpenRemote Keycloak 23.0.7.6.
    • Starts real Keycloak, PostgreSQL, and OpenRemote Manager services.
    • Creates victim consoles through the real API using an authenticated owner token, recording their owner links.
    • Sends no-Authorization registration requests containing each known victim ID and attacker-selected names/tokens.
    • Runs two vulnerable attempts and requires HTTP 200 plus persisted attacker values.
    • Starts the fixed release against the same runtime stack, runs two controls, and requires HTTP 403 plus unchanged persisted values.
    • Writes bundle/repro/runtime_manifest.json on every attempt.
  3. Success ends with:

    VULNERABLE_ATTEMPT_1_CONFIRMED: anonymous known-ID request overwrote owner-linked console metadata and push token.
    VULNERABLE_ATTEMPT_2_CONFIRMED: anonymous known-ID request overwrote owner-linked console metadata and push token.
    FIXED_ATTEMPT_1_CONFIRMED: HTTP 403 and original owner-linked console state retained.
    FIXED_ATTEMPT_2_CONFIRMED: HTTP 403 and original owner-linked console state retained.
    REPRODUCTION_SUCCESS: CVE-2026-66013 confirmed through the real OpenRemote HTTP API with repeated fixed-version negative controls.
    

Evidence

  • bundle/logs/reproduction_steps.log — orchestration and final per-attempt verdict markers.
  • bundle/logs/keycloak-service.log — real OpenRemote Keycloak startup and database-backed identity service.
  • bundle/logs/vulnerable-attempt-1-service.log — OpenRemote 1.25.0 service startup and both vulnerable requests. It includes Starting OpenRemote version: v1.25.0 and asset-update events showing attacker-selected values.
  • bundle/logs/fixed-attempt-1-service.log — OpenRemote 1.26.2 startup and both fixed controls. It includes Starting OpenRemote version: v1.26.2, HTTP 403, and Anonymous requests cannot update existing console registrations.
  • bundle/artifacts/openremote-console-cve-2026-66013/image-identities.json — source commits and SHA-256 identities of executed manager JARs and Keycloak runtime.
  • bundle/artifacts/openremote-console-cve-2026-66013/vulnerable-attempt-{1,2}/attacker-overwrite.request.txt — exact anonymous HTTP request shape; explicitly records Authorization: <ABSENT>.
  • bundle/artifacts/openremote-console-cve-2026-66013/vulnerable-attempt-{1,2}/attacker-overwrite.response.{headers,json} — HTTP 200 and response containing the known victim ID and attacker values.
  • bundle/artifacts/openremote-console-cve-2026-66013/vulnerable-attempt-{1,2}/persisted-state.json — database-backed proof of attacker name/token and owner_link_count: 1.
  • bundle/artifacts/openremote-console-cve-2026-66013/fixed-attempt-{1,2}/attacker-overwrite.response.{headers,json} — HTTP 403 and the fixed exception message.
  • bundle/artifacts/openremote-console-cve-2026-66013/fixed-attempt-{1,2}/persisted-state.json — original victim name/token remain, with one owner link.
  • bundle/repro/runtime_manifest.json — strict runtime evidence manifest for the real endpoint path.

Representative persisted vulnerable evidence has this form:

{"id":"<known-victim-id>","console_name":"ATTACKER_NAME_VULNERABLE_1","push_token":"ATTACKER_TOKEN_VULNERABLE_1","owner_link_count":1}

Representative fixed evidence has this form:

{"id":"<known-victim-id>","console_name":"VICTIM_FIXED_1","push_token":"VICTIM_TOKEN_FIXED_1","owner_link_count":1}

The primary proof uses no sanitizer and crosses the actual HTTP endpoint boundary into the real OpenRemote Manager product.

Recommendations / Next Steps

  • Upgrade to OpenRemote 1.26.2 or later.
  • Never allow anonymous registration to mutate an existing ID. Reject existing IDs for public requests or require a server-issued, device-bound registration secret.
  • For authenticated updates, enforce all of: matching request/object realm, current ownership link, and explicit mutation permission.
  • Keep anonymous creation and existing-console update as distinct authorization paths.
  • Add regression tests for anonymous existing-ID mutation, cross-realm IDs, another user's ID, nonexistent client-supplied IDs, and legitimate owner re-registration.
  • Consider rotating affected push tokens and reviewing console registration history where IDs may have been exposed.

Additional Notes

  • The reproduction script was run successfully in consecutive executions; it resets isolated runtime state and uses fresh victim asset IDs and markers each run.
  • Each execution performs two vulnerable requests and two fixed controls.
  • The script uses the vendor's exact manager and Keycloak OCI bytes, unpacked with skopeo/umoci because the worker's rootless Docker storage quota cannot hold the complete multi-service stack. The application entrypoint and HTTP behavior remain the real product, not a parser or mocked service.
  • Ubuntu's Apache-licensed TimescaleDB package lacks the optional HyperCore columnstore feature required by an unrelated datapoint migration. The script records that migration as applied after it reaches that specific compatibility error. Console assets, user links, registration, provider data, and the vulnerable endpoint do not use HyperCore; all relevant schema migrations and production code execute normally.
  • The known asset ID remains the principal practical precondition. The script obtains it from the authenticated victim creation response, then uses only that ID in the anonymous attack request.

CVE-2026-66013 Reproduction Transcript

The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.

Full session Replay every step — scrub the timeline or play it back.

Event 1/40
0:002:20
0:00
session startedgpt-5.6-sol · CVE-2026-66013 · REPRO-20
0:05
0:09
0:15
0:17
web search
0:19
web search
0:20
web search
0:32
web search
0:33
web search
0:34
0:37
0:43
0:45
0:58
0:58
0:59
web search
1:01
web search
2:06
2:06
2:06
2:06
2:06
2:06
extract_facts
no facts extracted
2:08
2:08
supportclaim_contract
2:15
2:15
2:15
2:15
2:20
08 · How to Fix

How to Fix CVE-2026-66013

Upgrade openremote · github to OpenRemote 1.26.2 and later. or later.

Coming soon

Step-by-step mitigation and hardening guidance for CVE-2026-66013 — configuration checks, workarounds where no patch exists, and how to verify you're protected — is on the way.

10 · FAQ

FAQ: CVE-2026-66013

Is CVE-2026-66013 exploitable?

Yes. Pruva independently reproduced CVE-2026-66013 in openremote and verified the exploit fires end-to-end in a sandboxed environment. A runnable proof-of-concept script and the full agent transcript are on this page (reproduction REPRO-2026-00300).

How severe is CVE-2026-66013?

CVE-2026-66013 is rated critical severity.

What type of vulnerability is CVE-2026-66013?

CVE-2026-66013 is classified as CWE-639 (Authorization Bypass Through User-Controlled Key), a Auth Bypass vulnerability.

Which versions of openremote are affected by CVE-2026-66013?

openremote OpenRemote <= 1.26.1; the advisory says the flaw was directly validated on 1.25.0. is affected by CVE-2026-66013.

Is there a fix for CVE-2026-66013?

Yes. CVE-2026-66013 is fixed in openremote OpenRemote 1.26.2 and later.. Upgrading to the fixed version remediates the issue.

How can I reproduce CVE-2026-66013?

Pruva provides a verified reproduction script on this page. Download it and run it inside an isolated environment such as a container or virtual machine — never against production. The reproduction was confirmed end-to-end by Pruva's automated agents.

Is the CVE-2026-66013 reproduction verified?

Yes. Pruva reproduced CVE-2026-66013 with high confidence in a sandboxed environment, capturing the full agent transcript and artifacts as evidence.
11 · References

References for CVE-2026-66013

Authoritative sources for CVE-2026-66013 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.