fix(browser): reject excessive viewport resizes

This commit is contained in:
Vincent Koc
2026-05-29 07:18:35 +02:00
parent cdeafd1895
commit 2e042fbca8
12 changed files with 104 additions and 6 deletions

View File

@@ -48,4 +48,16 @@ describe("browser navigation commands", () => {
expect(capture.runtimeErrors.join("\n")).toContain("Invalid width: must be a positive integer");
expect(mocks.runBrowserResizeWithOutput).not.toHaveBeenCalled();
});
it("rejects excessive resize dimensions before dispatch", async () => {
const program = createNavigationProgram();
await expect(
program.parseAsync(["browser", "resize", "8193", "768"], { from: "user" }),
).rejects.toThrow("__exit__:1");
const capture = getBrowserCliRuntimeCapture();
expect(capture.runtimeErrors.join("\n")).toContain("Invalid width: maximum is 8192");
expect(mocks.runBrowserResizeWithOutput).not.toHaveBeenCalled();
});
});

View File

@@ -1,5 +1,6 @@
import type { Command } from "commander";
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
import { ACT_MAX_VIEWPORT_DIMENSION } from "../../browser/act-policy.js";
import { runBrowserResizeWithOutput } from "../browser-cli-resize.js";
import { callBrowserRequest, type BrowserParentOpts } from "../browser-cli-shared.js";
import { danger, defaultRuntime } from "../core-api.js";
@@ -17,6 +18,11 @@ export function registerBrowserNavigationCommands(
defaultRuntime.exit(1);
return undefined;
}
if (parsed > ACT_MAX_VIEWPORT_DIMENSION) {
defaultRuntime.error(danger(`Invalid ${label}: maximum is ${ACT_MAX_VIEWPORT_DIMENSION}`));
defaultRuntime.exit(1);
return undefined;
}
return parsed;
};

View File

@@ -1,3 +1,4 @@
import { ACT_MAX_VIEWPORT_DIMENSION } from "../browser/act-policy.js";
import { callBrowserResize, type BrowserParentOpts } from "./browser-cli-shared.js";
import { danger, defaultRuntime } from "./core-api.js";
@@ -16,6 +17,13 @@ export async function runBrowserResizeWithOutput(params: {
defaultRuntime.exit(1);
return;
}
if (width > ACT_MAX_VIEWPORT_DIMENSION || height > ACT_MAX_VIEWPORT_DIMENSION) {
defaultRuntime.error(
danger(`width and height must not exceed ${ACT_MAX_VIEWPORT_DIMENSION}`),
);
defaultRuntime.exit(1);
return;
}
const result = await callBrowserResize(
params.parent,

View File

@@ -164,6 +164,14 @@ describe("browser state option collisions", () => {
expect(getBrowserCliRuntime().exit).toHaveBeenCalledWith(1);
});
it("rejects excessive viewport dimensions before resize dispatch", async () => {
await runBrowserCommand(["set", "viewport", "8193", "768"]);
expect(mocks.runBrowserResizeWithOutput).not.toHaveBeenCalled();
expectErrorMessage("Invalid width: maximum is 8192");
expect(getBrowserCliRuntime().exit).toHaveBeenCalledWith(1);
});
it("errors when set media receives an invalid value", async () => {
await runBrowserCommand(["set", "media", "sepia"]);

View File

@@ -4,6 +4,7 @@ import {
normalizeOptionalString,
} from "openclaw/plugin-sdk/string-coerce-runtime";
import { runCommandWithRuntime } from "../core-api.js";
import { ACT_MAX_VIEWPORT_DIMENSION } from "../browser/act-policy.js";
import { runBrowserResizeWithOutput } from "./browser-cli-resize.js";
import { callBrowserRequest, type BrowserParentOpts } from "./browser-cli-shared.js";
import { registerBrowserCookiesAndStorageCommands } from "./browser-cli-state.cookies-storage.js";
@@ -22,6 +23,11 @@ function parsePositiveInteger(value: unknown, label: string): number | undefined
defaultRuntime.exit(1);
return undefined;
}
if (parsed > ACT_MAX_VIEWPORT_DIMENSION) {
defaultRuntime.error(danger(`Invalid ${label}: maximum is ${ACT_MAX_VIEWPORT_DIMENSION}`));
defaultRuntime.exit(1);
return undefined;
}
return parsed;
}