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 [, relpath, lineStr] = m;
|
||||||
const line = Number(lineStr);
|
const line = Number(lineStr);
|
||||||
if (!line || !relpath) return false;
|
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)) {
|
if (!existsSync(abs)) {
|
||||||
f.evidence.push("[grounding: file not found]");
|
f.evidence.push("[grounding: file not found]");
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user