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 fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { describe, expect, it } from "vitest";
import { resolvePreferredOpenClawTmpDir } from "../infra/tmp-openclaw-dir.js";
import { buildRandomTempFilePath, withTempDownloadPath } from "./temp-path.js";
describe("buildRandomTempFilePath", () => {
@@ -17,13 +17,13 @@ describe("buildRandomTempFilePath", () => {
});
it("sanitizes prefix and extension to avoid path traversal segments", () => {
const tmpRoot = path.resolve(resolvePreferredOpenClawTmpDir());
const result = buildRandomTempFilePath({
prefix: "../../line/../media",
extension: "/../.jpg",
now: 123,
uuid: "abc",
});
const tmpRoot = path.resolve(os.tmpdir());
const resolved = path.resolve(result);
const rel = path.relative(tmpRoot, resolved);
expect(rel === ".." || rel.startsWith(`..${path.sep}`)).toBe(false);
@@ -45,11 +45,12 @@ describe("withTempDownloadPath", () => {
},
);
expect(capturedPath).toContain(path.join(os.tmpdir(), "line-media-"));
expect(capturedPath).toContain(path.join(resolvePreferredOpenClawTmpDir(), "line-media-"));
await expect(fs.stat(capturedPath)).rejects.toMatchObject({ code: "ENOENT" });
});
it("sanitizes prefix and fileName", async () => {
const tmpRoot = path.resolve(resolvePreferredOpenClawTmpDir());
let capturedPath = "";
await withTempDownloadPath(
{
@@ -61,7 +62,6 @@ describe("withTempDownloadPath", () => {
},
);
const tmpRoot = path.resolve(os.tmpdir());
const resolved = path.resolve(capturedPath);
const rel = path.relative(tmpRoot, resolved);
expect(rel === ".." || rel.startsWith(`..${path.sep}`)).toBe(false);