Back to skill

Security audit

Retrospect

Security checks for vulnerabilities and agentic risk

Overview

This skill performs a plausible session retrospective, but it can collect broader local assistant history than the current project and leaves sensitive transcript-derived files behind.

Install only if you are comfortable with the skill reading local assistant session logs and writing retrospective files into the project. Before using it, restrict input to an explicit session file or project-verified sessions, avoid broad auto-discovery of Codex/OpenCode histories, and remove or ignore generated transcript and feedback files if they may contain private prompts, tool outputs, or code.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T05 · Unauthorized Access and Privilege Escalation

Error
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: High

Vulnerable 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

  1. Require reliable project association before accepting a Codex or OpenCode session.
  2. Parse each session's metadata and compare its recorded working directory or project root with the canonicalized projectDir.
  3. Reject records whose project identity is absent, ambiguous, or outside the requested project.
  4. Prefer explicit user-selected session files when a platform does not provide dependable project metadata.
  5. Display the final list of selected files and request confirmation before processing them.
  6. Use canonical path comparison and account for symbolic links when matching project roots.
  7. Add automated tests proving that sessions associated with unrelated project directories are excluded.
  8. 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.

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:27
Finding

Predictable Shared Temporary File Used for Sensitive Session Transcripts

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, line 27
Vulnerability Type: Unsafe temporary-file handling
Risk Level: Medium

Vulnerable Code

bash
node ${CLAUDE_SKILL_DIR}/scripts/parse_session.js --project-dir "$(pwd)" > /tmp/session_transcript.md

Technical Analysis

The documented command writes sensitive conversation history to the fixed path /tmp/session_transcript.md. Shared temporary directories commonly permit other local users or processes to create entries. Shell output redirection opens the destination before executing the command, follows symbolic links, and truncates an existing target.

Because the path is predictable and no ownership, file-type, or permission validation occurs, another local process may pre-create it as a symbolic link. The invoking shell could then overwrite a different file writable by the victim. The predictable path also creates confidentiality and race-condition concerns: another process can monitor, replace, or attempt to read the transcript while it is being generated.

The command does not establish restrictive permissions explicitly and the instructions do not delete the transcript after analysis. Actual readability depends on the user's umask and platform configuration, but the design does not ensure private storage.

Attack Path

  1. A local attacker predicts that the skill will use /tmp/session_transcript.md.
  2. Before invocation, the attacker creates that path as a symbolic link to a file writable by the victim, or monitors the path for creation.
  3. The user runs the documented command.
  4. Shell redirection follows the symbolic link and truncates or overwrites the linked target with transcript data.
  5. Alternatively, weak resulting permissions or subsequent path reuse allow another local process to access or alter the transcript.
  6. The transcript remains in /tmp after processing because no cleanup step is specified.

Successful symbolic-link exploitation is limited to targ ...[truncated 757 chars]

Remediation
View remediation

Remediation Suggestions

  1. Create a unique temporary directory or file with mktemp.
  2. Apply restrictive permissions explicitly and ensure the file is owned by the invoking user.
  3. Register cleanup with a shell trap so the transcript is deleted on success, failure, or interruption.
  4. Do not use a predictable filename in a shared directory.
  5. Avoid reopening a temporary path by name where possible; piping transcript content directly to the analysis component is safer.
  6. If a file is necessary, verify that it is a regular file and not a symbolic link before use.
  7. Ensure the analysis process cannot replace the temporary file between validation and reading.

For example:

bash
tmp_dir="$(mktemp -d "${TMPDIR:-/tmp}/retrospect.XXXXXXXX")" || exit 1
chmod 700 "$tmp_dir"
transcript="$tmp_dir/session_transcript.md"
trap 'rm -rf -- "$tmp_dir"' EXIT HUP INT TERM

umask 077
node "${CLAUDE_SKILL_DIR}/scripts/parse_session.js" \
  --project-dir "$(pwd)" > "$transcript"

Where supported, use descriptor-based secure creation or direct piping to further reduce time-of-check/time-of-use risks.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (8)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill’s declared purpose is a session retrospective, but its actual behavior includes filesystem discovery of all project session logs, transcript extraction, and persistence of derived outputs. That mismatch prevents meaningful user consent and can expose far more conversation history than a user requesting a simple review would reasonably expect.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The activation conditions are broad enough to trigger on ordinary requests for reflection, feedback, or review, which increases the chance the skill runs in situations where the user did not intend project-wide transcript analysis. Overbroad triggering is dangerous here because the skill performs sensitive data collection and file-writing side effects.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The manifest suggests reviewing a current or past session, but the instructions default to analyzing all sessions in the project. This broadens data access beyond the apparent user request and can sweep in unrelated or sensitive prior conversations without clear authorization.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill description does not clearly warn that it will analyze all project conversation sessions and write feedback files to the project root. This omission undermines informed consent and makes the data access and persistence side effects more hazardous in normal use.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Writing FEEDBACK_TO_HUMAN.md and FEEDBACK_TO_LLM.md to the project root creates persistent artifacts containing analysis of conversation history, which may include sensitive prompts, errors, or behavioral assessments. For a retrospective skill, this persistence is not obviously necessary and may surprise users or leak information into the repository or shared workspace.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The generated Markdown includes raw user, assistant, system, and tool-result text with only length truncation, not privacy filtering. As a result, sensitive prompts, credentials, file contents, command outputs, or hidden instructions may be exposed in the transcript output without any warning or sanitization.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script enumerates and reads session files from multiple local assistant data stores, then emits transcript content directly to stdout. For a retrospective skill, this is overbroad data access: it can collect and disclose unrelated historical conversations, including prompts, system messages, tool outputs, and potentially secrets, far beyond the current session under review.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code searches ~/.claude, ~/.codex, and opencode session directories and ingests any JSONL files found there, including conversations from other tools and projects. This cross-application access materially expands the trust boundary and enables unintended aggregation of sensitive local history unrelated to the user's requested retrospective.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.