Security/Browser: constrain trace and download output paths to OpenClaw temp roots (#15652)

* Browser/Security: constrain trace and download output paths to temp roots

* Changelog: remove advisory ID from pre-public security note

* Browser/Security: constrain trace and download output paths to temp roots

* Changelog: remove advisory ID from pre-public security note

* test(bluebubbles): align timeout status expectation to 408

* test(discord): remove unused race-condition counter in threading test

* test(bluebubbles): align timeout status expectation to 408
This commit is contained in:
Mariano
2026-02-13 19:24:33 +00:00
committed by GitHub
parent 08725270e2
commit 7f0489e473
10 changed files with 166 additions and 16 deletions

View File

@@ -0,0 +1,28 @@
import path from "node:path";
import { resolvePreferredOpenClawTmpDir } from "../../infra/tmp-openclaw-dir.js";
export const DEFAULT_BROWSER_TMP_DIR = resolvePreferredOpenClawTmpDir();
export const DEFAULT_TRACE_DIR = DEFAULT_BROWSER_TMP_DIR;
export const DEFAULT_DOWNLOAD_DIR = path.join(DEFAULT_BROWSER_TMP_DIR, "downloads");
export function resolvePathWithinRoot(params: {
rootDir: string;
requestedPath: string;
scopeLabel: string;
defaultFileName?: string;
}): { ok: true; path: string } | { ok: false; error: string } {
const root = path.resolve(params.rootDir);
const raw = params.requestedPath.trim();
if (!raw) {
if (!params.defaultFileName) {
return { ok: false, error: "path is required" };
}
return { ok: true, path: path.join(root, params.defaultFileName) };
}
const resolved = path.resolve(root, raw);
const rel = path.relative(root, resolved);
if (!rel || rel.startsWith("..") || path.isAbsolute(rel)) {
return { ok: false, error: `Invalid path: must stay within ${params.scopeLabel}` };
}
return { ok: true, path: resolved };
}