fix: fail closed on sandbox media mapping errors

This commit is contained in:
Gustavo Madeira Santana
2026-04-14 16:50:51 -04:00
parent 397d8eae21
commit 48206b5627
2 changed files with 23 additions and 7 deletions

View File

@@ -162,6 +162,28 @@ describe("createReplyMediaPathNormalizer", () => {
expect(resolveOutboundAttachmentFromUrl).not.toHaveBeenCalled();
});
it("drops absolute host-local media paths when sandbox mapping fails", async () => {
ensureSandboxWorkspaceForSession.mockResolvedValue({
workspaceDir: "/tmp/sandboxes/session-1",
containerWorkdir: "/workspace",
});
const normalize = createReplyMediaPathNormalizer({
cfg: { tools: { fs: { workspaceOnly: false } } },
sessionKey: "session-key",
workspaceDir: "/tmp/agent-workspace",
});
const result = await normalize({
mediaUrls: ["/Users/peter/Documents/report.pdf"],
});
expect(result).toMatchObject({
mediaUrl: undefined,
mediaUrls: undefined,
});
expect(resolveOutboundAttachmentFromUrl).not.toHaveBeenCalled();
});
it("stages absolute workspace media paths so the PR scenario now works", async () => {
const absolutePath = "/Users/peter/.openclaw/workspace/exports/images/chart.png";
const normalize = createReplyMediaPathNormalizer({

View File

@@ -187,19 +187,13 @@ export function createReplyMediaPathNormalizer(params: {
sandboxRoot,
});
} catch (err) {
if (!isLikelyLocalMediaSource(media)) {
throw err;
}
if (FILE_URL_RE.test(media)) {
throw new Error(
"Host-local MEDIA file URLs are blocked in normal replies. Use a safe path or the message tool.",
{ cause: err },
);
}
if (isRelativeLocalMedia) {
return await persistLocalReplyMedia(resolveWorkspaceRelativeMedia(media));
}
return await persistLocalReplyMedia(media);
throw err;
}
return await persistLocalReplyMedia(sandboxResolvedMedia);
}