Session infrastructure: OpenRouter + tree-split reducer + observer→LLM Team + scrum_applier #11
@ -364,7 +364,21 @@ async function computeGrounding(findings: Finding[]): Promise<{ total: number; v
|
||||
const [, relpath, lineStr] = m;
|
||||
const line = Number(lineStr);
|
||||
if (!line || !relpath) return false;
|
||||
const abs = relpath.startsWith("/") ? relpath : resolve(REPO_ROOT, relpath);
|
||||
|
||||
// Path-traversal guard (caught 2026-04-27 by Kimi self-audit on
|
||||
// dd77632). A model output emitting `../../../etc/passwd:1` would
|
||||
// otherwise resolve outside REPO_ROOT and we'd readFile() a system
|
||||
// file. Resolve, then verify the absolute path is anchored under
|
||||
// REPO_ROOT — refuse anything that escapes (relative ".." traversal
|
||||
// OR an absolute path that doesn't start with REPO_ROOT). Existing
|
||||
// grounding-citation conventions all use repo-relative paths, so
|
||||
// this rejection is safe in practice.
|
||||
const abs = resolve(REPO_ROOT, relpath);
|
||||
if (!abs.startsWith(REPO_ROOT + "/") && abs !== REPO_ROOT) {
|
||||
f.evidence.push(`[grounding: path escapes repo root, refusing]`);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!existsSync(abs)) {
|
||||
f.evidence.push("[grounding: file not found]");
|
||||
return false;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user