mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-05 10:10:20 +00:00
fix(security): harden workspace bootstrap boundary reads
This commit is contained in:
@@ -166,4 +166,28 @@ Never do Y.
|
||||
expect(result).toContain("Rule 2");
|
||||
expect(result).not.toContain("Other Section");
|
||||
});
|
||||
|
||||
it.runIf(process.platform !== "win32")(
|
||||
"returns null when AGENTS.md is a symlink escaping workspace",
|
||||
async () => {
|
||||
const outside = path.join(tmpDir, "outside-secret.txt");
|
||||
fs.writeFileSync(outside, "secret");
|
||||
fs.symlinkSync(outside, path.join(tmpDir, "AGENTS.md"));
|
||||
|
||||
const result = await readPostCompactionContext(tmpDir);
|
||||
expect(result).toBeNull();
|
||||
},
|
||||
);
|
||||
|
||||
it.runIf(process.platform !== "win32")(
|
||||
"returns null when AGENTS.md is a hardlink alias",
|
||||
async () => {
|
||||
const outside = path.join(tmpDir, "outside-secret.txt");
|
||||
fs.writeFileSync(outside, "secret");
|
||||
fs.linkSync(outside, path.join(tmpDir, "AGENTS.md"));
|
||||
|
||||
const result = await readPostCompactionContext(tmpDir);
|
||||
expect(result).toBeNull();
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { openBoundaryFile } from "../../infra/boundary-file-read.js";
|
||||
|
||||
const MAX_CONTEXT_CHARS = 3000;
|
||||
|
||||
@@ -11,11 +12,21 @@ export async function readPostCompactionContext(workspaceDir: string): Promise<s
|
||||
const agentsPath = path.join(workspaceDir, "AGENTS.md");
|
||||
|
||||
try {
|
||||
if (!fs.existsSync(agentsPath)) {
|
||||
const opened = await openBoundaryFile({
|
||||
absolutePath: agentsPath,
|
||||
rootPath: workspaceDir,
|
||||
boundaryLabel: "workspace root",
|
||||
});
|
||||
if (!opened.ok) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const content = await fs.promises.readFile(agentsPath, "utf-8");
|
||||
const content = (() => {
|
||||
try {
|
||||
return fs.readFileSync(opened.fd, "utf-8");
|
||||
} finally {
|
||||
fs.closeSync(opened.fd);
|
||||
}
|
||||
})();
|
||||
|
||||
// Extract "## Session Startup" and "## Red Lines" sections
|
||||
// Each section ends at the next "## " heading or end of file
|
||||
|
||||
Reference in New Issue
Block a user