mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-18 06:36:29 +00:00
fix(browser): preserve strict CDP discovery policy on target-list lookup (#102328)
* fix(browser): preserve strict CDP discovery policy on target-list lookup findPageByTargetIdViaTargetList fetched the CDP /json/list endpoint without passing an ssrfPolicy argument, so the caller's discovery policy was dropped at the fetch layer while the sibling tryTerminateExecutionViaCdp scoped it. Build the scoped control policy with scopeCdpPolicyToConfiguredEndpoint and pass it to fetchJson, matching the sibling lookup path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(browser): tighten target-list CDP policy test comment Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(browser): consolidate target-list SSRF coverage --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: Peter Steinberger <steipete@gmail.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
// Browser tests cover pw session.get page for targetid.extension fallback plugin behavior.
|
||||
import type { SsrFPolicy } from "openclaw/plugin-sdk/ssrf-runtime";
|
||||
import { chromium } from "playwright-core";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import * as chromeModule from "./chrome.js";
|
||||
@@ -9,6 +10,19 @@ import {
|
||||
setCdpConnectRetryDelayMsForTests,
|
||||
} from "./pw-session.js";
|
||||
|
||||
const fetchWithSsrFGuardSpy = vi.hoisted(() => vi.fn());
|
||||
|
||||
vi.mock("openclaw/plugin-sdk/ssrf-runtime", async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import("openclaw/plugin-sdk/ssrf-runtime")>();
|
||||
return {
|
||||
...actual,
|
||||
fetchWithSsrFGuard: (...args: Parameters<typeof actual.fetchWithSsrFGuard>) => {
|
||||
fetchWithSsrFGuardSpy(...args);
|
||||
return actual.fetchWithSsrFGuard(...args);
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const connectOverCdpSpy = vi.spyOn(chromium, "connectOverCDP");
|
||||
const getChromeWebSocketUrlSpy = vi.spyOn(chromeModule, "getChromeWebSocketUrl");
|
||||
|
||||
@@ -84,6 +98,7 @@ function makeBrowser(pages: MockPageSpec[]): BrowserMockBundle {
|
||||
afterEach(async () => {
|
||||
connectOverCdpSpy.mockReset();
|
||||
getChromeWebSocketUrlSpy.mockReset();
|
||||
fetchWithSsrFGuardSpy.mockClear();
|
||||
setCdpConnectRetryDelayMsForTests();
|
||||
await closePlaywrightBrowserConnection().catch(() => {});
|
||||
});
|
||||
@@ -196,9 +211,17 @@ describe("pw-session getPageForTargetId", () => {
|
||||
const resolved = await getPageForTargetId({
|
||||
cdpUrl: "http://127.0.0.1:19993",
|
||||
targetId: "TARGET_B",
|
||||
ssrfPolicy: {
|
||||
dangerouslyAllowPrivateNetwork: false,
|
||||
allowRfc2544BenchmarkRange: true,
|
||||
},
|
||||
});
|
||||
expect(resolved).toBe(pageB);
|
||||
expect(newCDPSession).toHaveBeenCalled();
|
||||
expect(fetchWithSsrFGuardSpy).toHaveBeenCalledTimes(1);
|
||||
const policy = fetchWithSsrFGuardSpy.mock.calls[0]?.[0]?.policy as SsrFPolicy | undefined;
|
||||
expect(policy?.allowRfc2544BenchmarkRange).toBe(true);
|
||||
expect(policy?.hostnameAllowlist).toEqual(["127.0.0.1"]);
|
||||
} finally {
|
||||
fetchSpy.mockRestore();
|
||||
}
|
||||
|
||||
@@ -1201,13 +1201,14 @@ async function findPageByTargetIdViaTargetList(
|
||||
): Promise<Page | null> {
|
||||
const cdpHttpBase = normalizeCdpHttpBaseForJsonEndpoints(cdpUrl);
|
||||
await assertCdpEndpointAllowed(cdpUrl, ssrfPolicy);
|
||||
const cdpControlPolicy = scopeCdpPolicyToConfiguredEndpoint(cdpUrl, ssrfPolicy);
|
||||
const targets = await fetchJson<
|
||||
Array<{
|
||||
id: string;
|
||||
url: string;
|
||||
title?: string;
|
||||
}>
|
||||
>(appendCdpPath(cdpHttpBase, "/json/list"), 2000);
|
||||
>(appendCdpPath(cdpHttpBase, "/json/list"), 2000, undefined, cdpControlPolicy);
|
||||
return matchPageByTargetList(pages, targets, targetId);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user