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.
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).
CVE-2026-66013 Severity
CVE-2026-66013 is rated critical severity.
Critical — the most severe class — typically remotely exploitable with severe impact. Treat as an emergency.
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 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 Proof of Reproduction for CVE-2026-66013
- 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
Unauthenticated JSON registration body containing a known existing console asset ID, replacement console metadata, and replacement push provider token
- POST /api/master/console/register
- ConsoleResourceImpl.register()
- AssetStorageService.merge(existing ConsoleAsset)
How the agent worked
Root Cause and Exploit Chain for CVE-2026-66013
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()behindPOST /api/{realm}/console/register. - Affected versions: Advisory range
<= 1.26.1; the runtime proof uses the vendoropenremote/manager:1.25.0image (source commit0ed159ba423de28896ab77a07427cdc32ed0712a). - 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:
- Lines 83–90 read the submitted ID and perform
assetStorageService.find(id, true), which globally loads the existing asset. - The only check is that the object is a
ConsoleAsset; there is no authentication, ownership-link, or realm equality check. - Lines 106–125 copy attacker-controlled name, provider map, version, and platform into that existing asset.
- Lines 128–130 call
assetStorageService.merge(consoleAsset), persisting the changes. - 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
Run
bundle/repro/reproduction_steps.shfrom any directory (optionally setPRUVA_ROOTto the bundle path).The script:
- Resolves the prepared project cache from
bundle/project_cache_context.jsonand 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-
Authorizationregistration 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.jsonon every attempt.
- Resolves the prepared project cache from
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 includesStarting OpenRemote version: v1.25.0and asset-update events showing attacker-selected values.bundle/logs/fixed-attempt-1-service.log— OpenRemote 1.26.2 startup and both fixed controls. It includesStarting OpenRemote version: v1.26.2, HTTP 403, andAnonymous 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 recordsAuthorization: <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 andowner_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/umocibecause 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.
Artifacts and Evidence for CVE-2026-66013
Scripts, logs, diffs, and output captured during the reproduction.
How to Fix CVE-2026-66013
Upgrade openremote · github to OpenRemote 1.26.2 and later. or later.
FAQ: CVE-2026-66013
Is CVE-2026-66013 exploitable?
How severe is CVE-2026-66013?
What type of vulnerability is CVE-2026-66013?
Which versions of openremote are affected by CVE-2026-66013?
Is there a fix for CVE-2026-66013?
How can I reproduce CVE-2026-66013?
Is the CVE-2026-66013 reproduction verified?
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.