Back to skill

Security audit

Zai Usage

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to monitor Z.AI usage as advertised, but it handles a browser session token in risky ways and its scripts execute local env files as shell code.

Review before installing. Use this only if you are comfortable giving the skill a Z.AI browser-session bearer token and sending it to Z.AI's quota API. Store the token with restrictive permissions, avoid putting it in shell history or synced folders, and consider rotating the token after use. The safer implementation would parse one documented token file instead of sourcing env files as executable shell code.

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/usage-summary.sh:32
Finding

Credential Files Are Executed as Arbitrary Shell Code

Content
View full analysis
/dev/null ``` ### Technical Analysis The Bash `source` command does not treat an environment file as passive key-value data. It parses and executes every shell construct in the file within the current process. Consequently, a file intended only to contain `ZAI_JWT_TOKEN=...` can also contain command substitutions, function calls, redirections, or arbitrary commands. For example, a malicious `.env` file could contain: ```bash ZAI_JWT_TOKEN=dummy malicious_command ``` The command would run as soon as any affected usage-monitoring script loads the file. The full script additionally searches three locations, including `$SKILL_DIR/.env`, increasing the number of files that can become a code-execution source. Exploitation requires the attacker to gain write access to one of the sourced files or control it through a compromised installation or deployment p ...[truncated 1283 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
README.md:69
Finding

Documented Token Setup Does Not Enforce Restrictive File Permissions

Content
View full analysis
~/.openclaw/secrets/zai.env ``` The README separately claims at `README.md:183-186`: ```markdown ## Security - Tokens are stored in `~/.openclaw/secrets/zai.env` - Never displayed in logs or responses - File permissions: `600` (owner read/write only) ``` The setup guidance printed by `scripts/usage-summary.sh:126` similarly uses: ```bash echo 'ZAI_JWT_TOKEN=eyJhbGci...' > ~/.openclaw/secrets/zai.env ``` ### Technical Analysis Shell output redirection creates a file using permissions determined by the process's current `umask`. Neither documented setup command sets a restrictive `umask` nor applies `chmod 600` after creating the credential file. As a result, the stated `600` security property is not guaranteed. For example, under a permissive `umask`, the file may be readable by group members or other local users. The containing directory is also created without an explicit mode, so its permissions similarly depend on the existing directory and active `umask`. The file contains a bearer JWT. Any process or local account capable of reading it may be able to reuse the credential without knowing the user's password. ### Attack Path 1. A user follows the documented setup command under a permissive `umask`. 2. `~/.openclaw/secrets/zai.env` is created with permissions that permit access by another local user or group. 3. Another local account reads the file and extracts `ZAI_JWT_TOKEN`. 4. The attacker submits the token as an Authorization bearer credential to Z.AI. 5. The attacker receives whatever account or quota access is authorized by that token until it expires or is revoked. This p ...[truncated 778 chars]
Remediation
View remediation
"$HOME/.openclaw/secrets/zai.env" chmod 600 "$HOME/.openclaw/secrets/zai.env" ``` Additional hardening should include: 1. Updating both `README.md` and `SKILL.md` with the secure command. 2. Updating the setup message in `usage-summary.sh`. 3. Checking file ownership and mode before reading the token. 4. Rejecting symbolic links and files not owned by the invoking user. 5. Warning the user when the token file has group or world permissions. 6. Recommending immediate token rotation if the file was previously exposed. ]]>
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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (18)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared purpose is quota monitoring, but the setup instructs users to retrieve and store a JWT bearer token from browser local storage, which is a sensitive credential. A skill that reads secrets from local files or environment variables without clearly declaring that behavior expands trust beyond its stated purpose and could enable credential exposure or misuse if the scripts are modified, compromised, or invoked unexpectedly.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

Reading a credential file from the skill directory is risky because the script uses source, which executes any shell code in that file. In the context of a third-party skill, a colocated .env file is especially dangerous because it could be supplied or modified as part of the skill package, leading to code execution and credential theft.

Content

Scanner excerpt · scripts/usage-summary.sh (reported line 42)May include surrounding context.

sh
fi

    # Try skill directory
    if [ -f "$SKILL_DIR/.env" ]; then
        source "$SKILL_DIR/.env"
        [ -n "$ZAI_JWT_TOKEN" ] && return 0
    fi

Credential Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

This line completes the dangerous pattern by executing the skill-local .env content and then trusting the resulting ZAI_JWT_TOKEN value. In a skill-distribution context, this makes the package more dangerous because untrusted repository content can influence execution before any API call occurs.

Content

Scanner excerpt · scripts/usage-summary.sh (reported line 43)May include surrounding context.

sh
# Try skill directory
    if [ -f "$SKILL_DIR/.env" ]; then
        source "$SKILL_DIR/.env"
        [ -n "$ZAI_JWT_TOKEN" ] && return 0
    fi

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README instructs users to extract a JWT from browser local storage and reuse it in a local secrets file or environment variable, but it does not clearly emphasize that this is a live session credential that may grant account access or allow quota consumption if exposed. Using a browser-session token outside its original context increases credential-handling risk, especially if users copy it into shell history, backups, or less-protected environments.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
91% confidence
Finding

The instructions recommend persisting a browser-session JWT in a local file and alternatively in a shell environment variable. Persisting session credentials increases the chance of theft through local compromise, accidental inclusion in backups, shell history, process inspection, or reuse by other tools, and the credential appears to be a bearer token with direct account utility.

Content

Scanner excerpt · README.md (reported line 76)May include surrounding context.

Add your token to OpenClaw secrets:

bash
mkdir -p ~/.openclaw/secrets
echo "ZAI_JWT_TOKEN=eyJhbGci..." > ~/.openclaw/secrets/zai.env

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

md
- Tokens are stored in `~/.openclaw/secrets/zai.env`
- Never displayed in logs or responses
- File permissions: `600` (owner read/write only)

## Troubleshooting

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill advertises shell-executable usage via script paths in Quick Start, but does not declare any tool scope or permissions. This creates a transparency and least-privilege problem: users and hosting agents may not realize the skill needs command execution, increasing the chance that shell actions run without appropriate review or sandboxing.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The setup process tells users to extract a JWT from browser local storage and save it in a plaintext local env file, but provides no warning that this token is sensitive and may grant account access. This normalizes unsafe credential handling and increases the risk of token leakage through shell history, backups, file permissions issues, logs, or accidental sharing.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The invocation examples are phrased like ordinary conversation rather than explicit skill commands, making accidental triggering more likely in agentic environments. If auto-invoked, the skill could access local secrets or run shell scripts when a user merely asks a general question about credit usage, which increases the chance of unintended sensitive operations.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · README.md (reported line 128)May include surrounding context.

md
fi

RESPONSE=$(curl -s -H "Authorization: Bearer $ZAI_JWT_TOKEN" \
  "https://api.z.ai/api/monitor/usage/quota/limit" 2>/dev/null)

if ! echo "$RESPONSE" | jq -e '.success == true' > /dev/null 2>&1; then
    echo "ZAI: Auth error"

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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/check-usage.sh (reported line 19)May include surrounding context.

sh
fi

RESPONSE=$(curl -s -H "Authorization: Bearer $ZAI_JWT_TOKEN" \
  "https://api.z.ai/api/monitor/usage/quota/limit" 2>/dev/null)

if ! echo "$RESPONSE" | jq -e '.success == true' > /dev/null 2>&1; then
    echo "ZAI: Auth error"

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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/quick-check.sh (reported line 12)May include surrounding context.

sh
fi

RESPONSE=$(curl -s -H "Authorization: Bearer $ZAI_JWT_TOKEN" \
  "https://api.z.ai/api/monitor/usage/quota/limit" 2>/dev/null)

if ! echo "$RESPONSE" | jq -e '.success == true' > /dev/null 2>&1; then
    echo "ZAI: Auth error"

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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/usage-summary.sh (reported line 138)May include surrounding context.

sh
fi

RESPONSE=$(curl -s -H "Authorization: Bearer $ZAI_JWT_TOKEN" \
  "https://api.z.ai/api/monitor/usage/quota/limit" 2>/dev/null)

if ! echo "$RESPONSE" | jq -e '.success == true' > /dev/null 2>&1; then
    echo "ZAI: Auth error"

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script explicitly instructs users to retrieve a JWT from browser local storage via DevTools, which encourages manual extraction of a sensitive session token outside normal API key handling. That broadens credential exposure risk and can lead users to mishandle a bearer token that may grant more access than just usage monitoring.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The script automatically loads and sources multiple files likely to contain secrets, including files in the skill directory and home directory, without warning or validating their contents. Because shell source executes shell code, a malicious or tampered env file could run commands in the user's shell context, making this more serious than simple credential reading.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/usage-summary.sh (reported line 65)May include surrounding context.

sh
if [ ${#missing[@]} -gt 0 ]; then
        echo "Error: Missing required tools: ${missing[*]}"
        echo "Install with: sudo apt install ${missing[*]}"
        exit 1
    fi
}

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script sends a bearer token to a remote endpoint, but the only notice is in comments and setup text rather than a clear runtime disclosure. For a skill that handles credentials, lack of explicit user-facing warning reduces informed consent and increases the chance users supply powerful tokens without understanding they will be transmitted off-host.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The manifest describes a usage-monitoring skill that tracks quota and subscription status, which justifies calling the Z.AI API, but it does not mention reading credentials from a local secrets file. Accessing ~/.openclaw/secrets/zai.env introduces a local secret-reading capability beyond the user-visible purpose of simply checking usage.

Content

No source excerpt is available for this finding.