fix(browser): validate profile cdp urls

This commit is contained in:
Agustin Rivera
2026-04-03 18:33:50 +00:00
committed by Peter Steinberger
parent 36cc397548
commit aefc6fc161
2 changed files with 26 additions and 0 deletions

View File

@@ -141,6 +141,30 @@ describe("BrowserProfilesService", () => {
);
});
it("rejects private-network cdpUrl when strict SSRF mode is enabled", async () => {
const resolved = resolveBrowserConfig({
ssrfPolicy: { dangerouslyAllowPrivateNetwork: false },
});
const { ctx } = createCtx(resolved);
vi.mocked(loadConfig).mockReturnValue({
browser: {
ssrfPolicy: { dangerouslyAllowPrivateNetwork: false },
profiles: {},
},
});
const service = createBrowserProfilesService(ctx);
await expect(
service.createProfile({
name: "remote",
cdpUrl: "http://10.0.0.42:9222",
}),
).rejects.toThrow(/private\/internal\/special-use ip address/i);
expect(writeConfigFile).not.toHaveBeenCalled();
});
it("creates existing-session profiles as attach-only local entries", async () => {
const resolved = resolveBrowserConfig({});
const { ctx, state } = createCtx(resolved);

View File

@@ -4,6 +4,7 @@ import type { BrowserProfileConfig, OpenClawConfig } from "../config/config.js";
import { loadConfig, writeConfigFile } from "../config/config.js";
import { deriveDefaultBrowserCdpPortRange } from "../config/port-defaults.js";
import { resolveUserPath } from "../utils.js";
import { assertCdpEndpointAllowed } from "./cdp.helpers.js";
import { resolveOpenClawUserDataDir } from "./chrome.js";
import { parseHttpUrl, resolveProfile } from "./config.js";
import {
@@ -124,6 +125,7 @@ export function createBrowserProfilesService(ctx: BrowserRouteContext) {
let parsed: ReturnType<typeof parseHttpUrl>;
try {
parsed = parseHttpUrl(rawCdpUrl, "browser.profiles.cdpUrl");
await assertCdpEndpointAllowed(parsed.normalized, state.resolved.ssrfPolicy);
} catch (err) {
throw new BrowserValidationError(String(err));
}