T05 · Unauthorized Access and Privilege Escalation
- Location
scripts/parse_session.js:234- Finding
Cross-Project Collection of Codex and OpenCode Session Logs
- Content
View full analysis
Vulnerability Details
File Location:
scripts/parse_session.js, lines 234–261
Vulnerability Type: Excessive access to user-wide session history
Risk Level: HighVulnerable Code
js // Codex: ~/.codex/sessions/*.jsonl const codexPath = path.join(os.homedir(), ".codex", "sessions"); if (fs.existsSync(codexPath)) { for (const f of fs.readdirSync(codexPath)) { if (!f.endsWith(".jsonl")) continue; const full = path.join(codexPath, f); if (fs.statSync(full).isFile()) { sessions.push({ file: full, mtime: fs.statSync(full).mtimeMs }); } } } // OpenCode: platform-dependent const ocPath = process.platform === "darwin" ? path.join(os.homedir(), "Library", "Application Support", "opencode", "sessions") : path.join(os.homedir(), ".local", "share", "opencode", "sessions"); if (fs.existsSync(ocPath)) { for (const f of fs.readdirSync(ocPath)) { if (!f.endsWith(".jsonl")) continue; const full = path.join(ocPath, f); if (fs.statSync(full).isFile()) { sessions.push({ file: full, mtime: fs.statSync(full).mtimeMs }); } } }Technical Analysis
The documented purpose is to analyze conversation sessions associated with the current project. Claude Code discovery attempts to constrain collection through an encoded project path, but the Codex and OpenCode branches enumerate every top-level JSONL file in user-wide session directories.
The function receives
projectDir, but it does not use that value to validate whether Codex or OpenCode records belong to the selected project. Consequently, invoking the parser from one project can collect conversations from unrelated projects. These records are parsed into a combined transcript, which the skill instructions then direct an analysis subagent to process.This violates least-privilege and data-minimization principles. Session logs may contain proprietary source code, personal conversations, system instructions, local paths, command output, or credentia ...[truncated 1444 chars]
- Remediation
View remediation
Remediation Suggestions
- Require reliable project association before accepting a Codex or OpenCode session.
- Parse each session's metadata and compare its recorded working directory or project root with the canonicalized
projectDir. - Reject records whose project identity is absent, ambiguous, or outside the requested project.
- Prefer explicit user-selected session files when a platform does not provide dependable project metadata.
- Display the final list of selected files and request confirmation before processing them.
- Use canonical path comparison and account for symbolic links when matching project roots.
- Add automated tests proving that sessions associated with unrelated project directories are excluded.
- Avoid passing unrelated system messages, tool output, and secrets to the analysis subagent.
A safe filtering pattern should follow this design:
js const requestedProject = fs.realpathSync(projectDir); for (const candidate of candidateSessions) { const metadata = readSessionMetadata(candidate); if (!metadata.projectDir) continue; const sessionProject = fs.realpathSync(metadata.projectDir); if (sessionProject !== requestedProject) continue; sessions.push(candidate); }If project metadata cannot be extracted reliably, fail closed rather than collecting every session.
