Back to skill

Security audit

ContextKeeper

Security checks for vulnerabilities and agentic risk

Overview

This skill is meant to save project context, but it under-discloses persistent local writes and command-running scripts that have unsafe parsing and path handling issues.

Review before installing. Use it only if you want local project summaries and git metadata stored under ~/.memory/contextkeeper, avoid putting secrets in checkpoint messages, and prefer fixing the timestamp parsing, project ID validation, file permissions, and symlink/file-creation behavior before running the scripts on sensitive projects.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/dashboard.sh:53
Finding

Arbitrary Python Code Execution Through an Unescaped Stored Timestamp

Content
View full analysis
/dev/null | head -1 | sed 's/.*: *"\([^"]*\)".*/\1/') # Convert timestamp to relative time (with improved error handling) REL_TIME="" if [ -n "$TIMESTAMP" ] && command -v python3 > /dev/null 2>&1; then REL_TIME=$(python3 -c " from datetime import datetime try: ts = '${TIMESTAMP}'.replace('Z', '+00:00') td = datetime.utcnow() - datetime.fromisoformat(ts) mins = int(td.total_seconds() // 60) if mins < 1: print('just now') elif mins < 60: print(f'{mins}m ago') elif mins < 1440: print(f'{mins//60}h {mins%60}m ago') else: print(f'{mins//1440}d ago') except Exception: pass " 2>/dev/null) fi ``` ### Technical Analysis The dashboard extracts `timestamp` from the file referenced by `~/.memory/contextkeeper/current-state.json` using text-processing utilities rather than a JSON parser. It then directly interpolates the extracted value into Python source code inside a single-quoted Python string. A timestamp containing a single quote can terminate that string and introduce additional Python statements. Shell quoting does not make this safe because the interpolation occurs while Bash constructs the argument passed to `python3 -c`. Consequently, a malicious checkpoint can cause arbitrary Python code to execute when the dashboard is opened. The normal checkpoint generator creates a fixed-format timestamp. Exploitation therefore requires an attacker or another process to modify the persistent state file or redirect the `current-state.json` symlink to crafted content. The dashboard explicitly accepts and reads that symlink, making stored state a security boundary that should not be trusted as executable source. ### Attack Path 1. The attacker obtains the ability to cre ...[truncated 1014 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/ckpt.sh:70
Finding

Directory Traversal Through the Project Override Argument

Content
View full analysis
"$PROJECTS_DIR/$PROJECT_ID/latest.json" << JSON { "project_id": "$PROJECT_ID", "project_name": "$PROJECT_NAME", "last_checkpoint": "$TIMESTAMP", "git_dir": "$GIT_DIR", "status": "active" } JSON ``` ### Technical Analysis The second command-line argument is accepted as `PROJECT_OVERRIDE` and assigned directly to `PROJECT_ID`. The value is then concatenated into a filesystem path without character validation or canonical-path containment checking. An override containing `../` components can escape `~/.memory/contextkeeper/projects`. The script subsequently creates the resulting directory path and truncates or creates a file named `latest.json` at that location. The attacker cannot choose the final filename independently because the script always appends `latest.json`, but the attacker can select an unintended parent directory accessible to the invoking user. Embedded quotes, line breaks, and other special characters can also corrupt the generated JSON because `PROJECT_ID` and `GIT_DIR` are not JSON-escaped in this document. ### Attack Path 1. An attacker causes the script to be invoked with a crafted second argument, for example: ```bash ./scripts/ckpt.sh "checkpoint" "../../../chosen-directory" ``` 2. The script assigns the traversal string to `PROJECT_ID`. 3. `mkdir -p` resolves the traversal co ...[truncated 829 chars]
Remediation
View remediation
&2 exit 1 fi ``` - Do not permit slashes, dots, control characters, or empty path components in an identifier. - Canonicalize the destination and verify that it remains a child of `PROJECTS_DIR` before writing. - Use a JSON-aware tool or library to serialize every value, including `PROJECT_ID` and `GIT_DIR`. - Write to a securely created temporary file and atomically rename it into place. - If arbitrary project labels are required, store them as JSON data while deriving the directory name from a safe internal identifier. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/ckpt.sh:91
Finding

Predictable Checkpoint Filename Enables Symlink-Following File Overwrite

Content
View full analysis
"$CHECKPOINTS_DIR/$TIMESTAMP.json" << JSON ``` ### Technical Analysis Checkpoint names are derived only from the current local time with one-second resolution. The destination is opened using ordinary shell redirection, which truncates an existing file and follows symbolic links. If a malicious process can write within the checkpoint directory, it can predict the filename for an upcoming invocation and pre-create that path as a symlink to another file. When the checkpoint is generated, the shell follows the symlink and truncates the target. The practical exploitability depends on write access to the checkpoint directory. Properly enforced mode `0700` would substantially mitigate cross-account exploitation, but the script does not itself establish such permissions. ### Attack Path 1. The attacker has write access to `~/.memory/contextkee ...[truncated 904 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/ckpt.sh:8
Finding

Sensitive Repository Metadata Stored Without Enforced Restrictive Permissions

Content
View full analysis
"$CHECKPOINTS_DIR/$TIMESTAMP.json" << JSON { "id": "$TIMESTAMP", "timestamp": "$ISO_TIMESTAMP", "project_id": "$PROJECT_ID", "project_name": "$SAFE_PROJECT_NAME", "session_type": "active_development", "summary": "$SAFE_MESSAGE", "git_branch": "$SAFE_BRANCH", "recent_commits": "$SAFE_RECENT_COMMITS", "files_touched": [$FILES_JSON], "urls": [], "commands": [], "next_steps": [], "auto_detected": true } JSON # Create/update project state mkdir -p "$PROJECTS_DIR/$PROJECT_ID" cat > "$PROJECTS_DIR/$PROJECT_ID/latest.json" << JSON { "project_id": "$PROJECT_ID", "project_name": "$PROJECT_NAME", "last_checkpoint": "$TIMESTAMP", "git_dir": "$GIT_DIR", "status": "active" } JSON ``` ### Technical Analysis The checkpoint contains user-supplied summaries, repository branch names, recent commit text, modified filenames, and the absolute repository path. This information can reveal internal project names, directory layouts, development activity, and text that the user may reasonably expect to remain private. The script creates directories and files without setting `umask 077` or explicitly applying modes `0700` and `0600`. Their effective permissions therefore depend on the caller's inherited umask. Under a common umask of `022`, new directories may be mode `0755` and files may be mode `0644`, allowing other local accounts to read stored metadata when parent-directory traversal permissions also permit access. ### Attack Path 1. A user runs `ckpt.sh` with a permissive umask. 2. The script creates the state directories and ...[truncated 833 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (13)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

This is a true transparency and trust-boundary issue: the skill markets itself as only doing safe manual checkpointing with validated inputs, while the finding indicates it also executes external utilities, modifies filesystem state, and performs dashboard/status logic beyond the stated scope. In an agent setting, deceptive or incomplete behavior descriptions increase the chance of unsafe invocation because operators may rely on the metadata to decide whether the skill can run in restricted environments.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

This is a true transparency and trust-boundary issue: the skill markets itself as only doing safe manual checkpointing with validated inputs, while the finding indicates it also executes external utilities, modifies filesystem state, and performs dashboard/status logic beyond the stated scope. In an agent setting, deceptive or incomplete behavior descriptions increase the chance of unsafe invocation because operators may rely on the metadata to decide whether the skill can run in restricted environments.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The guide says 'No Binary Required' and later 'No Code Required,' yet it specifies shell commands, JavaScript trigger logic, cron-based writes, and future hooks. This mismatch is dangerous because it can lower reviewer and agent suspicion while still introducing executable behaviors and state-changing automation.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The document materially expands the skill from a manual, non-executing note-taking aid into an automated system that writes files via cron/session-end hooks and a checkpoint script. That creates an execution and persistence surface not disclosed by the skill metadata, increasing the chance an agent will perform unauthorized file modifications or automation based on a document framed as 'conceptual.'

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The document proposes automatic checkpoint writes on session end without a clear warning that persistent files will be modified. Hidden or implicit persistence is dangerous because users may disclose sensitive information under the assumption of ephemeral interaction, while the skill silently stores it.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The integration guidance encourages reading and reusing accumulated checkpoints, dashboards, and stale-context summaries without any stated sensitivity filtering or retention limits. That creates a privacy and data-minimization problem: secrets, personal data, or unrelated prior-session details may be retained and surfaced later.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · references/implementation.md (reported line 104)May include surrounding context.

DateDecisionRationaleReversible
2026-02-18Use localtunnel over VPS directFaster testing, no firewallYes
2026-02-18GitHub Pages for PWAFree, auto-deployYes
text

## Blocker Tracking

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The trigger regexes match common phrases like 'pick up,' 'remind me,' 'status,' and ambiguous pronouns such as 'it' or 'that.' Overbroad triggers can cause unintended state loading, checkpointing, or contextual reuse from ordinary conversation, which is risky in a skill that persists and reuses prior context.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The git-aware checkpoint script adds repository inspection, branch discovery, modified-file enumeration, and current-state updates beyond the stated manual checkpoint purpose. Even if not overtly malicious, this broadens data access and persistence in ways that may expose project structure or sensitive filenames and encourages agents to inspect repositories without a clear need-to-know basis.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The procedural instruction to check PROJECTS.md before responding encourages broad dependence on previously accumulated user context for future answers. Without strict scoping and sanitization, this can lead to unnecessary retrieval of historical data, privacy leakage, or stale-context contamination affecting current responses.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The script claims validated inputs, but the project override is accepted verbatim and later used in filesystem paths and JSON output. An attacker supplying values like '../otherdir' could cause directory creation or file writes outside the intended project namespace under ~/.memory/contextkeeper/projects, enabling local path traversal and corruption of adjacent files within the user's writable area.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The manifest describes manual checkpoint creation with validated inputs, but the script automatically detects the current git repository and harvests branch, recent commits, and changed file names. That expands behavior beyond a purely manual, input-driven checkpoint and records project context derived from the environment.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · scripts/dashboard.sh (reported line 141)May include surrounding context.

sh
# Quick Actions
echo "${BOLD}Quick Actions${RESET}"
echo "─────────────────────────────────────────"
echo " ckpt.sh                 # Create checkpoint"
echo " ckpt.sh \"message\"      # Checkpoint with summary"
echo " dashboard.sh            # View project state"
echo " ls ~/.memory/contextkeeper/  # Browse checkpoints"

Static analysis

No suspicious patterns detected.