Medium severity5.8NVD Advisory· Published Apr 28, 2026· Updated Apr 28, 2026
CVE-2026-41372
CVE-2026-41372
Description
OpenClaw before 2026.4.2 fails to normalize trailing-dot localhost hosts in remote CDP discovery responses, allowing bypass of loopback protections. Attackers can craft hostile discovery responses returning localhost. to retarget authenticated browser control toward localhost endpoints and expose browser state.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
openclawnpm | < 2026.4.2 | 2026.4.2 |
Affected products
1Patches
19c22d6366973Browser: normalize localhost absolute-form CDP hosts (#59236)
4 files changed · +22 −2
CHANGELOG.md+1 −0 modified@@ -53,6 +53,7 @@ Docs: https://docs.openclaw.ai - ACP/gateway reconnects: reject stale pre-ack ACP prompts after reconnect grace expiry so callers fail cleanly instead of hanging indefinitely when the gateway never confirms the run. - Providers/Copilot: classify native GitHub Copilot API hosts in the shared provider endpoint resolver and harden token-derived proxy endpoint parsing so Copilot base URL routing stays centralized and fails closed on malformed hints. Thanks @vincentkoc. - Gateway: prune empty `node-pending-work` state entries after explicit acknowledgments and natural expiry so the per-node state map no longer grows indefinitely. (#58179) Thanks @gavyngong. +- Browser/CDP: normalize trailing-dot localhost absolute-form hosts before loopback checks so remote CDP websocket URLs like `ws://localhost.:...` rewrite back to the configured remote host. (#59236) Thanks @mappel-nv. ## 2026.4.1-beta.1
extensions/browser/src/browser/cdp.test.ts+8 −0 modified@@ -320,6 +320,14 @@ describe("cdp", () => { expect(normalized).toBe("wss://user:pass@example.com/devtools/browser/ABC?token=abc"); }); + it("rewrites localhost absolute-form websocket URLs for remote CDP hosts", () => { + const normalized = normalizeCdpWsUrl( + "ws://localhost.:9222/devtools/browser/ABC", + "https://user:pass@example.com?token=abc", + ); + expect(normalized).toBe("wss://user:pass@example.com/devtools/browser/ABC?token=abc"); + }); + it("rewrites 0.0.0.0 wildcard bind address to remote CDP host", () => { const normalized = normalizeCdpWsUrl( "ws://0.0.0.0:3000/devtools/browser/ABC",
src/gateway/net.test.ts+10 −0 modified@@ -3,6 +3,7 @@ import { afterEach, describe, expect, it, vi } from "vitest"; import { makeNetworkInterfacesSnapshot } from "../test-helpers/network-interfaces.js"; import { isLocalishHost, + isLoopbackHost, isPrivateOrLoopbackAddress, isPrivateOrLoopbackHost, isSecureWebSocketUrl, @@ -28,6 +29,7 @@ describe("isLocalishHost", () => { it("accepts loopback and tailscale serve/funnel host headers", () => { const accepted = [ "localhost", + "localhost.:18789", "127.0.0.1:18789", "[::1]:18789", "[::ffff:127.0.0.1]:18789", @@ -46,6 +48,13 @@ describe("isLocalishHost", () => { }); }); +describe("isLoopbackHost", () => { + it("accepts localhost absolute-form hostnames", () => { + expect(isLoopbackHost("localhost.")).toBe(true); + expect(isLoopbackHost("LOCALHOST...")).toBe(true); + }); +}); + describe("isTrustedProxyAddress", () => { it.each([ { @@ -394,6 +403,7 @@ describe("isPrivateOrLoopbackAddress", () => { describe("isPrivateOrLoopbackHost", () => { it("accepts localhost", () => { expect(isPrivateOrLoopbackHost("localhost")).toBe(true); + expect(isPrivateOrLoopbackHost("localhost.")).toBe(true); }); it("accepts loopback addresses", () => {
src/gateway/net.ts+3 −2 modified@@ -400,8 +400,9 @@ function parseHostForAddressChecks( return null; } const normalizedHost = host.trim().toLowerCase(); - if (normalizedHost === "localhost") { - return { isLocalhost: true, unbracketedHost: normalizedHost }; + const canonicalHost = normalizedHost.replace(/\.+$/, ""); + if (canonicalHost === "localhost") { + return { isLocalhost: true, unbracketedHost: canonicalHost }; } return { isLocalhost: false,
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/openclaw/openclaw/commit/9c22d636697336a6b22b0ae24798d8b8325d7828nvdPatchWEB
- github.com/advisories/GHSA-fh32-73r9-rgh5ghsaADVISORY
- github.com/openclaw/openclaw/security/advisories/GHSA-fh32-73r9-rgh5nvdVendor AdvisoryWEB
- nvd.nist.gov/vuln/detail/CVE-2026-41372ghsaADVISORY
- www.vulncheck.com/advisories/openclaw-loopback-protection-bypass-via-trailing-dot-localhost-in-cdp-discoverynvdThird Party AdvisoryWEB
News mentions
0No linked articles in our index yet.