Back to skill

Security audit

Memory Keeper

Security checks for vulnerabilities and agentic risk

Overview

This skill has a coherent backup purpose, but it handles highly sensitive agent memory and can push it to remote Git repositories with weak warnings and unsafe credential handling.

Review and redact memory files before using this skill. Prefer local-only archives unless you fully trust the destination, never use the documented CrimsonDevil333333 remote for your own memories, and do not embed tokens in Git URLs or commands. Avoid `--push` and broad `--allow-extra` patterns unless you have verified the repository is private, owned by you, and the files contain no secrets.

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 (2)

other

Error
Location
references/usage.md:5
Finding
Documentation Directs Sensitive Agent Memory to an Author-Controlled Repository## Vulnerability Details **File Location**: `references/usage.md:5-9` **Vulnerability Type**: Unauthorized sensitive-data transmission **Risk Level**: High ### Vulnerable Code ```markdown 1. Update the workspace memory files (`memory/*.md`, `MEMORY.md`, and `AGENTS.md`, `SOUL.md`, `USER.md`, `TOOLS.md`, `HEARTBEAT.md`) as you go. 2. Run Memory Keeper to copy them to a dedicated archive directory or git repo, e.g.: ```bash python3 skills/memory-keeper/scripts/memory_sync.py --target ~/clawdy-memories --commit --message "Post-session sync" --remote https://github.com/CrimsonDevil333333/clawdy-memories.git --push ``` ``` The documented command invokes the following upload behavior in `scripts/memory_sync.py:100-108`: ```python commit_result = True if args.commit: commit_result = commit_and_push(target, args) ``` ```python if args.remote: configure_remote(target, args.remote) if args.push: git_args = ["push", "--set-upstream", "origin", args.branch] run_git_command(target, git_args) ``` ### Technical Analysis The “Typical workflow” command configures a repository owned by `CrimsonDevil333333` rather than a neutral placeholder or a repository controlled by the operator. The files being committed include agent memory, user information, personality instructions, tool configuration, and operational context. When the example is followed with `--commit` and `--push`, the implementation stages the copied files, creates a commit, changes the `origin` remote to the supplied URL, and executes `git push`. The push only succeeds if the executing user possesses write access to that repository, but the documentation nevertheless directs an attempted transfer of sensitive data to a specific third party. There is no destination ownership validation, confirmation prompt, sensitivity warning, or allowlist before the upload. ### Attack Path 1. An operator or agent follows the documented “ ...[truncated 1121 chars]
Remediation
## Remediation Suggestions - Replace the author-controlled URL with an unmistakable placeholder such as `https://github.com/YOUR-ACCOUNT/YOUR-PRIVATE-REPOSITORY.git`. - Explicitly instruct operators to use only repositories they own and whose visibility and access controls they have verified. - Require interactive confirmation before the first push, showing the resolved remote hostname, repository owner, and files to be transmitted. - Refuse or warn when a documented or preconfigured third-party repository is selected. - Add a dry-run mode that lists included files and the destination without copying or transmitting data. - Add secret scanning and an explicit exclusion mechanism before staging the archive. - Document that memory files may contain sensitive personal data, credentials, internal instructions, and system information.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/memory_sync.py:53
Finding
Git Remote Credentials Are Persisted in Plaintext and Can Be Re-Uploaded## Vulnerability Details **File Location**: `scripts/memory_sync.py:53-92` **Vulnerability Type**: Plaintext credential exposure **Risk Level**: High ### Vulnerable Code The complete remote configuration logic stores the supplied URL in Git configuration: ```python def configure_remote(dest: Path, remote_url: str, remote_name: str = "origin") -> None: try: existing = run_git_command(dest, ["remote", "get-url", remote_name]) current_url = existing.stdout.decode().strip() except subprocess.CalledProcessError: current_url = "" if current_url != remote_url: if current_url: run_git_command(dest, ["remote", "remove", remote_name]) run_git_command(dest, ["remote", "add", remote_name, remote_url]) ``` The complete log-entry construction records the supplied remote URL without sanitization: ```python def log_memory_update( workspace: Path, target: Path, commit: bool, push: bool, remote: Optional[str], timestamp: Optional[datetime] = None, ) -> None: timestamp = timestamp or datetime.now().astimezone() memory_dir = workspace / "memory" memory_dir.mkdir(parents=True, exist_ok=True) entry = ( f"- [{timestamp.strftime('%Y-%m-%d %H:%M:%S %Z')}] Memory Keeper synced to {target} " f"(commit={commit}, push={push}, remote={remote or 'none'})\n" ) log_file = memory_dir / f"{timestamp.date():%Y-%m-%d}.md" with open(log_file, "a", encoding="utf-8") as handle: handle.write(entry) ``` The unsafe practice is explicitly encouraged in `references/usage.md:33`: ```markdown **Remote refused or authentication failed**: Memory Keeper now surfaces the exact git command that failed and reminds you to configure your credential helper, SSH key, or embed a personal access token. ``` Error handling can additionally print the full failed command at `scripts/memory_sync ...[truncated 2721 chars]
Remediation
## Remediation Suggestions - Never recommend embedding personal access tokens in Git URLs. - Use Git credential helpers, SSH agents, platform credential managers, or short-lived environment-based authentication. - Sanitize remote URLs before logging. Remove user information and display only the scheme, hostname, and repository path. - Do not print raw subprocess arguments when they can contain credentials; apply centralized secret redaction before emitting errors. - Detect URLs containing passwords or tokens and reject them with a safe remediation message. - If compatibility requires credential-bearing URLs, strip credentials before saving the remote and provide authentication through a temporary credential helper. - Add tests confirming that passwords, tokens, URL user information, and common credential patterns never appear in memory journals or error output. - Advise existing users to rotate potentially exposed tokens, rewrite affected Git history, remove credentials from `.git/config`, and inspect CI or scheduler logs.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (14)

Credential Access

High
Category
Privilege Escalation
Content
## Troubleshooting

- **`git` errors**: ensure the destination is writable and that you have `git` installed on your system.  
- **Remote refused or authentication failed**: Memory Keeper now surfaces the exact git command that failed and reminds you to configure your credential helper, SSH key, or embed a personal access token. Run `git remote -v` inside the archive to check the URL and try `GIT_ASKPASS=echo` + your token if needed.  
- **Files missing**: confirm you ran the command from the correct workspace or pass `--workspace` explicitly.

## Logging
Confidence
98% confidence
Finding
The troubleshooting guidance suggests embedding a personal access token and using `GIT_ASKPASS=echo` with the token, which encourages insecure credential handling and can expose secrets through shell history, process listings, logs, or accidental persistence in scripts. In a skill centered on archiving memory and configuration files, this is particularly dangerous because the same environment may later archive or log the very credential used for remote access.

Context-Inappropriate Capability

High
Confidence
96% confidence
Finding
The code allows configuring an arbitrary remote URL and later using it for push operations, enabling transmission of copied memory to any destination supplied at runtime. In the context of a memory-backup skill, this is dangerous because it adds unrestricted network egress for highly sensitive workspace state without meaningful destination validation.

Description-Behavior Mismatch

High
Confidence
97% confidence
Finding
The script can push archived memory files to a remote Git repository, which materially expands its behavior from local backup into external data transmission. Because the archived files include agent memory and configuration context, this can exfiltrate sensitive data to third-party infrastructure or attacker-controlled repositories.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The README explicitly promotes copying sensitive agent memory files and optionally pushing them to a remote Git repository, but it does not prominently warn that these files may contain secrets, credentials, private prompts, user data, or operational context. It also notes that each run appends sync metadata back into local memory logs, which can create additional persistence and disclosure of archive locations or remotes; in a memory-backup skill, this context makes the omission more dangerous because the primary payload is highly sensitive by design.

Lp3

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding
The skill advertises and instructs use of a Python CLI that reads workspace memory files, writes archives, and invokes git operations, yet the manifest declares no explicit tool scope or permissions. That omission weakens reviewability and can lead an agent or user to authorize broader file and shell access than necessary for a skill that handles highly sensitive context data.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The skill explicitly supports `--remote` and `--push` for archiving memory, AGENTS, SOUL, USER, and other context files, but the description does not clearly warn that these options can transmit sensitive agent memories and configuration to an external repository. Because the targeted files may contain secrets, system prompts, identities, or operational context, users may unknowingly exfiltrate highly sensitive data off-host.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The example command combines archiving with remote configuration and push, but the documentation does not warn that the targeted files may contain sensitive user, system, agent, or credential-related context. This omission is especially risky here because the skill is specifically designed to aggregate the agent's memory and configuration corpus, making accidental mass disclosure more likely and more damaging.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The usage documentation explicitly instructs users to copy memory/context files and optionally commit and push them to a remote Git repository, which extends the skill from local backup into external data transmission. Because the archived files include items like MEMORY.md, AGENTS.md, SOUL.md, USER.md, and TOOLS.md, this can expose sensitive agent state, configuration, prompts, or user data to a third-party service if misused or misconfigured.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
The automation tips recommend configuring the skill against a repository and describe routine use on agents, effectively normalizing publication of memory archives to remote infrastructure. In the context of a memory backup skill, this is dangerous because the contents are likely to include highly sensitive operational context and may be transferred off-host without adequate scrutiny or minimization.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The documentation recommends cron/heartbeat automation for repeated backups while only lightly cautioning against push noise, not against privacy or integrity risks from unattended collection and possible remote transmission. In this skill's context, unattended backup jobs can continuously replicate sensitive memory state and magnify the impact of a bad configuration, compromised remote, or inclusion of secrets.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def run_git_command(target: Path, args: List[str]) -> subprocess.CompletedProcess:
    return subprocess.run(["git", "-C", str(target)] + args, check=True, capture_output=True)


def copy_files(workspace: Path, dest: Path, include_memory: bool) -> None:
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
When --push is used, the script transmits archived memory data to a remote repository but provides no explicit user-facing warning about the sensitivity of the data being sent. In a skill whose purpose involves copying agent memory and configuration artifacts, lack of a disclosure warning materially raises the chance of accidental data leakage.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The --allow-extra option permits copying arbitrary relative files, glob matches, and whole directories beyond the documented memory/context files. This broadens the skill into a generic file collection mechanism, increasing the risk that secrets, credentials, source code, or unrelated personal data are silently swept into the archive and later exposed or transferred.

Natural-Language Policy Violations

Low
Confidence
78% confidence
Finding
The natural-language log entry is formatted with the host's local timezone via astimezone(), which imposes a locale-specific representation on generated records. There is no user opt-in or documentation explaining that local timezone formatting is intentional or configurable.

Static analysis

No suspicious patterns detected.