[GH-ISSUE #137] SafeOutputTree.cleanup exposes mutable internal cleanup state #84

Closed
opened 2026-10-15 18:20:57 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @morluto on GitHub (Jul 14, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/137

Problem

SafeOutputTree.cleanup returns the internal mutable #cleanup object directly. Consumers can mutate it after rollback and alter session-visible cleanup facts.

Reproduction

import { mkdtemp, rm } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { SafeOutputTree } from "./dist/artifacts/SafeOutputTree.js";

const parent = await mkdtemp(join(tmpdir(), "rea-safeout-parent-"));
const outputRoot = join(parent, "root");
const tree = await SafeOutputTree.create(outputRoot, {
  maxEntries: 1024,
  maxTotalBytes: 1024,
  maxEntryBytes: 1024,
  maxCompressionRatio: 2,
  maxDepth: 8,
  maxPathBytes: 1024,
});

const cleanup = await tree.rollback();
cleanup.residualPaths.push('/forged/path');

console.log(tree.cleanup.residualPaths); // -> ["/forged/path"]
await rm(parent, { recursive: true, force: true });

Impact

Rollback artifacts are intended to represent true filesystem cleanup state. By mutating the returned cleanup object, a caller can forge residual paths and potentially mislead callers that consume cleanup telemetry or enforce cleanup policy.

Expected behavior

Return a detached clone (including cloned residualPaths) so external callers cannot mutate internal state.

Originally created by @morluto on GitHub (Jul 14, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/137 ## Problem `SafeOutputTree.cleanup` returns the internal mutable `#cleanup` object directly. Consumers can mutate it after rollback and alter session-visible cleanup facts. ## Reproduction ```ts import { mkdtemp, rm } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { SafeOutputTree } from "./dist/artifacts/SafeOutputTree.js"; const parent = await mkdtemp(join(tmpdir(), "rea-safeout-parent-")); const outputRoot = join(parent, "root"); const tree = await SafeOutputTree.create(outputRoot, { maxEntries: 1024, maxTotalBytes: 1024, maxEntryBytes: 1024, maxCompressionRatio: 2, maxDepth: 8, maxPathBytes: 1024, }); const cleanup = await tree.rollback(); cleanup.residualPaths.push('/forged/path'); console.log(tree.cleanup.residualPaths); // -> ["/forged/path"] await rm(parent, { recursive: true, force: true }); ``` ## Impact Rollback artifacts are intended to represent true filesystem cleanup state. By mutating the returned `cleanup` object, a caller can forge residual paths and potentially mislead callers that consume cleanup telemetry or enforce cleanup policy. ## Expected behavior Return a detached clone (including cloned `residualPaths`) so external callers cannot mutate internal state.
bsakaguchi 2026-10-15 18:20:57 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#84
No description provided.