fix(security): lock sandbox tmp media paths to openclaw roots

This commit is contained in:
Peter Steinberger
2026-02-24 23:09:34 +00:00
parent bf8ca07deb
commit d3da67c7a9
13 changed files with 364 additions and 31 deletions

View File

@@ -1,7 +1,7 @@
import crypto from "node:crypto";
import { mkdtemp, rm } from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { resolvePreferredOpenClawTmpDir } from "../infra/tmp-openclaw-dir.js";
function sanitizePrefix(prefix: string): string {
const normalized = prefix.replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
@@ -27,6 +27,10 @@ function sanitizeFileName(fileName: string): string {
return normalized || "download.bin";
}
function resolveTempRoot(tmpDir?: string): string {
return tmpDir ?? resolvePreferredOpenClawTmpDir();
}
export function buildRandomTempFilePath(params: {
prefix: string;
extension?: string;
@@ -42,7 +46,7 @@ export function buildRandomTempFilePath(params: {
? Math.trunc(nowCandidate)
: Date.now();
const uuid = params.uuid?.trim() || crypto.randomUUID();
return path.join(params.tmpDir ?? os.tmpdir(), `${prefix}-${now}-${uuid}${extension}`);
return path.join(resolveTempRoot(params.tmpDir), `${prefix}-${now}-${uuid}${extension}`);
}
export async function withTempDownloadPath<T>(
@@ -53,7 +57,7 @@ export async function withTempDownloadPath<T>(
},
fn: (tmpPath: string) => Promise<T>,
): Promise<T> {
const tempRoot = params.tmpDir ?? os.tmpdir();
const tempRoot = resolveTempRoot(params.tmpDir);
const prefix = `${sanitizePrefix(params.prefix)}-`;
const dir = await mkdtemp(path.join(tempRoot, prefix));
const tmpPath = path.join(dir, sanitizeFileName(params.fileName ?? "download.bin"));