Back to skill

Security audit

Clawng Term Memory

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent backup purpose, but it automatically pushes sensitive agent state to GitHub and aggregates cross-agent memory with weak user controls.

Review the memory files before enabling this skill, use a private repository with least-privilege credentials, avoid git credential.helper store, and do not run the merge workflow unless you are comfortable aggregating and displaying all agent memories from the configured remote.

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)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/merge.sh:8
Finding
Sensitive agent memory is stored in an insecure temporary directory and exposed through output logs<![CDATA[ ## Vulnerability Details **File Location**: `scripts/merge.sh`, lines 8-38 **Vulnerability Type**: Unsafe temporary-file handling and plaintext sensitive-data exposure **Risk Level**: Medium ### Vulnerable Code ```bash STAGING_DIR="/tmp/clawng-merge-$$" cd "$WORKSPACE" mkdir -p "$STAGING_DIR" echo "[merge] Fetching all remote branches..." git fetch origin # Collect MEMORY.md from each agent branch AGENT_BRANCHES=$(git branch -r | grep 'origin/agent/' | sed 's|.*origin/||' | tr -d ' ') if [ -z "$AGENT_BRANCHES" ]; then echo "[merge] No agent branches found." rm -rf "$STAGING_DIR" exit 0 fi for branch in $AGENT_BRANCHES; do agent_id=$(echo "$branch" | sed 's|agent/||') memory=$(git show "origin/$branch:MEMORY.md" 2>/dev/null || echo "") if [ -n "$memory" ]; then echo "=== $agent_id ===" >> "$STAGING_DIR/all-memories.txt" echo "$memory" >> "$STAGING_DIR/all-memories.txt" echo "" >> "$STAGING_DIR/all-memories.txt" fi done echo "[merge] Staged memory files from: $AGENT_BRANCHES" echo "[merge] Output at: $STAGING_DIR/all-memories.txt" cat "$STAGING_DIR/all-memories.txt" ``` ### Technical Analysis The script creates a predictable temporary directory using its process ID: ```bash STAGING_DIR="/tmp/clawng-merge-$$" mkdir -p "$STAGING_DIR" ``` This construction does not provide atomic, secure temporary-directory creation. An attacker with local access may be able to predict the process ID and create the path before the script does. Depending on operating-system protections and account permissions, this can cause denial of service or facilitate unsafe path manipulation. The script also does not set a restrictive `umask` or explicitly assign owner-only permissions. It writes aggregated contents from every remote agent's `MEMORY.md` into a plaintext file. These files may contain user context, operational information, private conversations, or other sensitive long-term memory. The temporary directory is removed only when no ...[truncated 1935 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create the temporary directory atomically with `mktemp`. 2. Set an owner-only `umask` before creating files. 3. register an `EXIT` trap immediately so cleanup occurs on success, error, or interruption. 4. Do not print memory contents to standard output. 5. If a downstream process requires the generated file, pass its path through a protected channel and delete it immediately after use. 6. Explicitly create files with owner-only permissions where portability permits. 7. Ensure cron, CI, and service logs do not retain memory content. Example hardening: ```bash umask 077 STAGING_DIR=$(mktemp -d "${TMPDIR:-/tmp}/clawng-merge.XXXXXXXX") trap 'rm -rf -- "$STAGING_DIR"' EXIT HUP INT TERM OUTPUT_FILE="$STAGING_DIR/all-memories.txt" : > "$OUTPUT_FILE" chmod 600 "$OUTPUT_FILE" # Populate OUTPUT_FILE without printing its contents. echo "[merge] Memory collection completed." ``` A more robust design would avoid writing the aggregate to disk and instead stream it directly to the authorized synthesis process through a pipe or protected standard input. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:29
Finding
Documentation recommends plaintext persistent storage of Git credentials<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 29-34 **Vulnerability Type**: Insecure credential storage guidance **Risk Level**: Medium ### Vulnerable Code ```bash **HTTPS with credential store (no token in URL):** ```bash git remote add origin https://github.com/<user>/<repo>.git git config credential.helper store # Git will prompt for credentials on first push and store them securely ``` ``` ### Technical Analysis The setup instructions configure Git's `store` credential helper: ```bash git config credential.helper store ``` The `store` helper persists credentials unencrypted on disk, commonly in `~/.git-credentials`. The accompanying statement that credentials will be stored “securely” is therefore misleading. Avoiding a token in the remote URL prevents one exposure mechanism, but it does not make the credential helper's storage encrypted or resistant to account-level compromise. This is particularly significant because the project is intended to push sensitive files—including `MEMORY.md`, `USER.md`, identity files, operating rules, daily notes, and installed skills—to a private repository. A stolen GitHub credential may allow an attacker to read that repository and, depending on the token's permissions, modify it or access additional repositories. ### Attack Path 1. A user follows the documented HTTPS setup procedure. 2. The user configures `credential.helper store`. 3. During the first authenticated push, Git saves the supplied username and credential in plaintext on disk. 4. A malicious process, compromised application, backup reader, or local user with access to the account's files reads the credential store. 5. The attacker uses the recovered credential against GitHub. 6. If the credential remains valid and has sufficient scope, the attacker clones the private agent-memory repository, modifies repository content, or accesses other resources authorized by the credential. This path requires prior access to files within ...[truncated 890 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Remove the recommendation to use Git's plaintext `store` helper. Replace it with one or more secure authentication options: 1. Prefer SSH authentication using a passphrase-protected private key and an operating-system SSH agent. 2. For HTTPS, recommend an operating-system-backed credential manager such as Git Credential Manager, macOS Keychain, or the appropriate Linux secret-service integration. 3. GitHub CLI authentication may be used where its credential handling is appropriate for the platform. 4. Recommend fine-grained, repository-specific tokens with only the minimum required permissions. 5. Require token expiration and document prompt revocation procedures. 6. Warn users not to place credentials in remote URLs, scripts, environment files committed to Git, or plaintext credential stores. 7. Advise existing users to remove and rotate credentials previously stored with the helper. Example documentation replacement: ```bash git remote add origin https://github.com/<user>/<repo>.git # Install and configure an OS-backed credential manager. git config --global credential.helper manager ``` The exact helper name should be verified for the supported operating system. The documentation should not claim secure storage unless the selected helper uses an OS-protected keychain or equivalent secret store. ]]>
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 (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The code generally aligns with the backup/version-control portion of the description: it stages core knowledge files, commits them, and tries to push to a remote repository. However, the declared purpose is broader than the supplied code. The script only performs commit/push on a machine-specific branch and shows the latest log line. It does not contain functionality for showing history beyond the last commit, diffing a file, reverting a change, restoring state on another machine, or cloning a repo. The per-host branch behavior is also a material implementation choice not reflected in the description, which implies a more general automatic GitHub push workflow.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description is about backing up and restoring an agent's core knowledge via git: committing, pushing to GitHub, and supporting history/diff/revert workflows. The supplied code does not implement those behaviors. Instead, it performs a different task: fetching remote branches, extracting MEMORY.md from each origin/agent/* branch, combining them into a temporary file in /tmp, and outputting the result. This is a materially different primary purpose and involves undeclared access to multiple remote agent branches and temporary staging for memory synthesis. Therefore the description does not accurately represent the code chunk.

Missing User Warnings

High
Confidence
97% confidence
Finding
The skill normalizes automatic pushing of SOUL.md, MEMORY.md, USER.md, IDENTITY.md, AGENTS.md, HEARTBEAT.md, and skills to GitHub without a prominent warning that these files may contain sensitive internal state, user data, prompts, secrets, or operational rules. In an agent-memory skill, automatic off-host synchronization materially increases the risk of data exfiltration and long-term retention of sensitive information.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The invocation guidance is broad enough that an agent may trigger this skill during routine edits, history inspection, or file operations, causing unexpected git commits and pushes. In this skill's context, that is dangerous because the tracked files include identity, memory, rules, and installed skills, which may contain sensitive or security-relevant information.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The daily synthesis design automatically aggregates MEMORY.md from multiple agent branches into SHARED_MEMORY.md with 'no human required,' but the documentation does not warn users that memories from different machines or roles will be merged and redistributed. In context, this can spread sensitive information across agents and systems, expanding access far beyond the original source and creating confidentiality, provenance, and contamination risks.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The script implements cross-branch aggregation of MEMORY.md from every remote agent branch, which exceeds the skill’s stated backup/history purpose of preserving a single agent’s core knowledge files. That broader data collection creates an unnecessary confidentiality boundary violation by exposing one agent’s memory to another synthesis workflow and to any user who runs the script.

Context-Inappropriate Capability

Medium
Confidence
93% confidence
Finding
Reading MEMORY.md from all remote agent branches is a privileged data-harvesting capability not justified by portable persistence or versioned backup. In this skill context, MEMORY.md likely contains sensitive operational context, prompts, or secrets, so consolidating it across branches materially increases the blast radius of any misuse or accidental disclosure.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The script writes aggregated memory content into a temporary file under /tmp without informing the user that potentially sensitive multi-agent data is being staged there. Even with mktemp-like uniqueness via PID, placing consolidated memory in a shared temporary location increases exposure to local disclosure, accidental collection, or later mishandling.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
Printing the full aggregated memory file to stdout can leak sensitive content into terminal scrollback, shell history adjacencies, CI logs, session recordings, or higher-level agent logs. In this skill context, MEMORY.md is likely to contain durable agent memory and operating context, making indiscriminate terminal output especially risky.

Intent-Code Divergence

Low
Confidence
97% confidence
Finding
The header comment says the script will collect memories for an AI synthesis agent to read and produce SHARED_MEMORY.md. In practice, the script only stages content into /tmp/clawng-merge-$$/all-memories.txt and cats that file; it never creates SHARED_MEMORY.md or invokes any synthesis step.

Static analysis

No suspicious patterns detected.