Back to skill

Security audit

Vanar Neutron Memory

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent remote memory skill, but it needs review because it can send and store conversation content remotely and inject recalled remote content back into the agent context with limited safeguards.

Install only if you are comfortable sending saved text, search queries, and optionally full conversation turns to the Neutron service. Prefer a service-specific NEUTRON_API_KEY, avoid the plaintext credentials file unless permissions are locked down, do not enable auto-capture or auto-recall for sensitive projects, and do not run with an untrusted NEUTRON_API_BASE value.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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 (3)

T01 · Skill Instruction Hijacking

Error
Location
hooks/pre-tool-use.sh:38
Finding

Untrusted Remote Memories Are Injected Directly into Agent Context

Content
View full analysis
/dev/null || echo "{}") # Extract memories if any memories=$(echo "$response" | jq -r '.results[]?.content // empty' 2>/dev/null | head -500) if [[ -n "$memories" ]]; then echo "---" echo "RECALLED MEMORIES:" echo "$memories" echo "---" fi ``` Related persistence behavior appears in `hooks/post-tool-use.sh:22-41`, where complete user and assistant messages can be stored automatically: ```bash USER_MSG="${OPENCLAW_USER_MESSAGE:-}" AI_RESP="${OPENCLAW_AI_RESPONSE:-}" [[ -z "$USER_MSG" && -z "$AI_RESP" ]] && exit 0 TS=$(date -u +"%Y-%m-%dT%H:%M:%SZ") TITLE="Conversation - ${TS}" CONTENT="User: ${USER_MSG} Assistant: ${AI_RESP}" # Build form field values safely using jq (prevents JSON injection) text_json=$(jq -n --arg t "$CONTENT" '[$t]') title_json=$(jq -n --arg t "$TITLE" '[$t]') curl -s -X POST "${API_BASE}/memory/save" \ -H "Authorization: Bearer ${API_KEY}" \ -F "text=${text_json}" \ -F 'textTypes=["text"]' \ -F 'textSources=["auto_capture"]' \ -F "textTitles=${title_json}" > /dev/null 2>&1 ``` ### Technical Analysis The pre-tool hook treats memory content returned by the remote service as trusted agent context. It extracts the `content` fields and prints them without separating data from instructions, filtering instruction-like text, attaching provenance, or warning the agent that the content is untrusted. When auto-capture is enabled, attacker-controlled user messages are stored as memories. An attacker can therefore submit text containing instructions designed to alter later agent behavior. Semantic search may recall ...[truncated 1938 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/neutron-memory.sh:4
Finding

Unrestricted API Endpoint Override Can Exfiltrate API Keys and Conversation Data

Content
View full analysis
&1) ``` ```bash result=$(curl -s -X POST "${API_BASE}/memory/search" \ -H "Authorization: Bearer ${API_KEY}" \ -H "Content-Type: application/json" \ -d "$json_body" 2>&1) ``` From `hooks/pre-tool-use.sh`: ```bash API_BASE="${NEUTRON_API_BASE:-https://api-neutron.vanarchain.com}" ``` ```bash response=$(curl -s -X POST "${API_BASE}/memory/search" \ -H "Authorization: Bearer ${API_KEY}" \ -H "Content-Type: application/json" \ -d "$json_body" 2>/dev/null || echo "{}") ``` From `hooks/post-tool-use.sh`: ```bash API_BASE="${NEUTRON_API_BASE:-https://api-neutron.vanarchain.com}" ``` ```bash curl -s -X POST "${API_BASE}/memory/save" \ -H "Authorization: Bearer ${API_KEY}" \ -F "text=${text_json}" \ -F 'textTypes=["text"]' \ -F 'textSources=["auto_capture"]' \ -F "textTitles=${title_json}" > /dev/null 2>&1 ``` ### Technical Analysis The `NEUTRON_API_BASE` environment variable can replace the intended service origin with any URL. No scheme validation, hostname allowlist, certificate pinning, or explicit development-mode restriction is applied. Every request sends `Authorization: Bearer ${API_KEY}` to the configured endpoint. Save operations and the auto-capture hook also transmit memory or conversation ...[truncated 2069 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SETUP.md:38
Finding

Credential Setup Instructions Do Not Enforce Restrictive File Permissions

Content
View full analysis
~/.config/neutron/credentials.json ``` ``` The same unsafe creation example is repeated by the CLI in `scripts/neutron-memory.sh:35-39`: ```bash echo "Option 2 - Credentials file:" echo " mkdir -p ~/.config/neutron" echo ' echo '"'"'{"api_key":"nk_your_key"}'"'"' > ~/.config/neutron/credentials.json' ``` ### Technical Analysis The documented setup creates the directory and credential file without explicitly restricting permissions. Resulting permissions depend on the user's current `umask`. Under a commonly used `022` umask, the file may be created with mode `0644`, making the API key readable by other local users on a multi-user system. The directory may similarly be created with mode `0755`. The runtime scripts only need read access to one Neutron credential. Reading that credential is necessary for the declared functionality, but allowing unrelated local accounts to read it exceeds the minimum privilege required. The issue is not a hardcoded production secret: the value shown is a placeholder. The risk arises from instructing users to place their real key in a potentially over-permissive plaintext file. ### Attack Path 1. A user follows Option B in the setup guide and substitutes a real Neutron API key. 2. The user's `umask` permits group or world read access when shell redirection creates the file. 3. Another local account enumerates or reads `~/.config/neutron/credentials.json`. 4. The attacker obtains the plaintext API key. 5. The attacker reuses the key against the Neutron API to perform operations available to that credential, potentially accessing memories or consuming account credits. This path requires local filesystem access under another accoun ...[truncated 542 chars]
Remediation
View remediation
"$HOME/.config/neutron/credentials.json" chmod 600 "$HOME/.config/neutron/credentials.json" ``` Additional hardening measures: 1. Update both `SETUP.md` and the CLI error message so they never recommend insecure file creation. 2. At runtime, inspect the credential file's ownership and mode before reading it. 3. Refuse or prominently warn when the file is owned by another user or is readable/writable by group or others. 4. Prefer a platform credential store or secret manager instead of a plaintext JSON file where practical. 5. Recommend `NEUTRON_API_KEY` rather than the generic `API_KEY` environment variable. 6. Document key rotation procedures for users who may already have created an over-permissive file. 7. Ensure logs and diagnostics never print the complete credential. ]]>
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
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (21)

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

The setup guide instructs users to write a plaintext API key directly into ~/.config/neutron/credentials.json. Storing long-lived credentials unencrypted on disk increases the risk of accidental disclosure through backups, local compromise, permissive file permissions, or dotfile syncing, especially because this skill enables persistent access to a remote memory service.

Content

Scanner excerpt · SETUP.md (reported line 40)May include surrounding context.

Option B — Credentials file:

bash
mkdir -p ~/.config/neutron
echo '{"api_key":"nk_your_key_here"}' > ~/.config/neutron/credentials.json

Option C — OpenClaw project config (openclaw.json):

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The skill’s description understates important behavior: it depends on a third-party service, uses credentials from environment configuration, performs network connectivity/authentication tests, and delegates persistence to an external API. In context, this is more dangerous because the skill’s core function is long-term memory, so users may provide highly sensitive personal or operational context that is then transmitted off-system under a simpler description than warranted.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The skill’s description understates important behavior: it depends on a third-party service, uses credentials from environment configuration, performs network connectivity/authentication tests, and delegates persistence to an external API. In context, this is more dangerous because the skill’s core function is long-term memory, so users may provide highly sensitive personal or operational context that is then transmitted off-system under a simpler description than warranted.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · hooks/post-tool-use.sh (reported line 12)May include surrounding context.

sh
command -v jq &> /dev/null || exit 0

API_BASE="${NEUTRON_API_BASE:-https://api-neutron.vanarchain.com}"
CONFIG_FILE="${HOME}/.config/neutron/credentials.json"

API_KEY="${API_KEY:-${NEUTRON_API_KEY:-}}"

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · hooks/pre-tool-use.sh (reported line 14)May include surrounding context.

sh
command -v jq &> /dev/null || exit 0

API_BASE="${NEUTRON_API_BASE:-https://api-neutron.vanarchain.com}"
CONFIG_FILE="${HOME}/.config/neutron/credentials.json"

API_KEY="${API_KEY:-${NEUTRON_API_KEY:-}}"

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

The script uses a plaintext credentials file in the user's home directory for API key storage, but it does not verify file permissions or encourage secure storage. On multi-user systems or misconfigured environments, this can expose the API key to other local users or backup/sync systems, enabling unauthorized API use.

Content

Scanner excerpt · scripts/neutron-memory.sh (reported line 5)May include surrounding context.

sh
# Neutron Memory CLI — save and search only

API_BASE="${NEUTRON_API_BASE:-https://api-neutron.vanarchain.com}"
CONFIG_FILE="${HOME}/.config/neutron/credentials.json"

# --- Dependency checks ---
if ! command -v curl &> /dev/null; then

Credential Access

High
Category
Privilege Escalation
Confidence
92% confidence
Finding

The usage instructions explicitly recommend writing the API key to a plaintext JSON file under ~/.config without setting restrictive permissions. This guidance can lead users to persist credentials insecurely, increasing the chance of local disclosure and downstream unauthorized access.

Content

Scanner excerpt · scripts/neutron-memory.sh (reported line 39)May include surrounding context.

sh
echo ""
    echo "Option 2 - Credentials file:"
    echo "  mkdir -p ~/.config/neutron"
    echo '  echo '"'"'{"api_key":"nk_your_key"}'"'"' > ~/.config/neutron/credentials.json'
    exit 1
fi

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 · SETUP.md (reported line 18)May include surrounding context.

md
Your account comes with **$20 of free credits** — enough to store and search thousands of memories.

> If you already have an account, log in at https://openclaw.vanarchain.com/login and go to **Manage** → **API Keys** to create a new key.

That's it — one key is all you need. No agent IDs, no app IDs, no other configuration.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill advertises and instructs use of shell scripts and hooks, but the manifest does not declare any explicit tool scope such as allowed shell access. In an agent setting, undeclared execution capability reduces reviewability and containment, making it easier for a skill to invoke shell-based behavior that operators did not explicitly approve.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The hook automatically packages and transmits full user and assistant conversation content to a remote API once enabled, while sourcing credentials from environment variables or a local credentials file. In a memory skill this is functionally related to the feature, but it still creates a real data-exfiltration path for potentially sensitive prompts, secrets, or proprietary context without per-message filtering, minimization, or explicit runtime consent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script sends complete conversation contents to a remote endpoint with no user-facing warning, confirmation, or visible audit trail at transmission time. Because post-turn hooks may run silently, this can expose secrets, personal data, internal code, or other sensitive material to an external service without sufficiently explicit awareness by the operator.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
92% confidence
Finding

The curl call exfiltrates the full user message to an external endpoint along with an authorization token. In a memory skill this is functionally expected, but it is still a genuine security concern because all prompt content is exported off-box and could expose confidential data depending on how the agent is used.

Content

Scanner excerpt · hooks/pre-tool-use.sh (reported line 39)May include surrounding context.

sh
json_body=$(jq -n --arg q "$USER_MESSAGE" '{"query":$q,"limit":5,"threshold":0.5}')

# Query for relevant memories
response=$(curl -s -X POST "${API_BASE}/memory/search" \
    -H "Authorization: Bearer ${API_KEY}" \
    -H "Content-Type: application/json" \
    -d "$json_body" 2>/dev/null || echo "{}")

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

When enabled, the hook sends the user's latest message to a remote API for semantic search before the agent turn. That creates a real privacy and data-handling risk because prompts may contain secrets, personal data, or proprietary information, and the script provides no in-band disclosure, consent check, or content minimization at transmission time.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script loads an API key from environment variables or a local credentials file, then uses it in Authorization headers for remote requests. While this behavior is functionally necessary, there is no explicit disclosure in the help text or comments aimed at users that credentials are being read from local storage and sent to an external service.

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/neutron-memory.sh (reported line 38)May include surrounding context.

sh
echo "  export API_KEY=nk_your_key"
    echo ""
    echo "Option 2 - Credentials file:"
    echo "  mkdir -p ~/.config/neutron"
    echo '  echo '"'"'{"api_key":"nk_your_key"}'"'"' > ~/.config/neutron/credentials.json'
    exit 1
fi

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script transmits user-supplied memory content and search queries to a remote third-party API, but it does not present any explicit privacy notice, consent prompt, or data-handling warning at the point of use. Because this skill is specifically designed for persistent memory across sessions, users may send sensitive information without realizing it leaves the local environment and is stored remotely.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
95% confidence
Finding

This search command sends user queries and the bearer API key to an external service. In the context of an agent memory skill, search terms may contain sensitive user context, secrets, or operational data, so remote transmission materially expands the data exposure boundary.

Content

Scanner excerpt · scripts/neutron-memory.sh (reported line 130)May include surrounding context.

sh
# Build JSON body safely using jq (prevents JSON injection)
        json_body=$(jq -n --arg q "$query" --argjson l "$limit" --argjson t "$threshold" \
            '{"query":$q,"limit":$l,"threshold":$t}')
        result=$(curl -s -X POST "${API_BASE}/memory/search" \
            -H "Authorization: Bearer ${API_KEY}" \
            -H "Content-Type: application/json" \
            -d "$json_body" 2>&1)

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/neutron-memory.sh (reported line 145)May include surrounding context.

sh
echo ""

        # Check connectivity + auth
        result=$(curl -s -w "\n%{http_code}" -X POST "${API_BASE}/memory/search" \
            -H "Authorization: Bearer ${API_KEY}" \
            -H "Content-Type: application/json" \
            -d '{"query":"test","limit":1}' 2>&1)

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/neutron-memory.sh (reported line 226)May include surrounding context.

sh
# Check API connectivity
        echo -n "API:     "
        http_code=$(curl -s -o /dev/null -w "%{http_code}" -X POST "${API_BASE}/memory/search" \
            -H "Authorization: Bearer ${API_KEY}" \
            -H "Content-Type: application/json" \
            -d '{"query":"ping","limit":1}' 2>/dev/null)

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
67% confidence
Finding

The inline documentation frames the behavior as opt-in only, but the implemented behavior is automatic capture of the entire conversation after every AI turn once the flag is enabled. That is not a direct contradiction in a strict sense, but the comment minimizes the operational effect of enabling the flag and can mislead reviewers about the extent of automated data capture.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The script accesses API credentials from environment variables or a local credentials file, then uses them in an Authorization header for an outbound request. This is a sensitive operation, and the script provides no user-facing notice, logging, or inline warning that stored credentials will be loaded and used automatically.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.