Back to skill

Security audit

Zyt TTS

Security checks for vulnerabilities and agentic risk

Overview

This Chanjing TTS skill is purpose-aligned and discloses its credential use, but users should treat its local credentials file as sensitive.

Install only if you intend to use Chanjing TTS and are comfortable storing app_id, secret_key, and cached access_token in a local JSON file. Keep ~/.chanjing or CHANJING_CONFIG_DIR private, avoid shared directories, and remember the credentials are sent to Chanjing's API to obtain tokens. Some scripts named in the documentation were not present in the reviewed artifact, so functionality may be incomplete.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/_auth.py:47
Finding
Credential File Permissions Are Applied Non-Atomically and Permission Failures Are Suppressed## Vulnerability Details **File Location**: `scripts/_auth.py:47-59` **Vulnerability Type**: Insecure credential storage **Risk Level**: Medium ```python def write_config(data): CONFIG_DIR.mkdir(parents=True, exist_ok=True) try: os.chmod(CONFIG_DIR, 0o700) except Exception: pass with open(CONFIG_FILE, "w", encoding="utf-8") as f: json.dump(data, f, indent=2, ensure_ascii=False) try: os.chmod(CONFIG_FILE, 0o600) except Exception: pass ``` ### Technical Analysis The configuration file contains `app_id`, `secret_key`, and a cached `access_token`. It is created using the process's default file-creation permissions and restricted to mode `0600` only after its contents have been written. This creates a non-atomic protection sequence in which the file's initial permissions depend on the active umask. The parent directory is similarly hardened after creation rather than created with a guaranteed restrictive mode. If the configured directory already exists, is shared, resides on a filesystem with unsuitable permission semantics, or a permission change fails, sensitive data may be exposed. Both `chmod` operations suppress every exception, so execution continues even when credential protection cannot be established. The implementation also does not verify the file's resulting owner, type, or permissions. ### Attack Path 1. A victim runs the Skill with a permissive umask or sets `CHANJING_CONFIG_DIR` to an existing shared or insufficiently protected directory. 2. `write_config()` opens and writes `credentials.json` using process-default creation permissions. 3. The subsequent `chmod()` fails, is ineffective on the selected filesystem, or cannot correct exposure that occurred during creation. 4. The exception is silently ignored, and the program continues as if credential storage were secure. 5. Another local user or process with directory access reads `credentials.json`. 6. The exposed `secret_key` or c ...[truncated 704 chars]
Remediation
## Remediation Suggestions - Create the configuration directory with mode `0700` from the outset and verify its ownership and final permissions. - Write credentials to a securely created temporary file using exclusive creation and mode `0600`, then atomically replace the destination with `os.replace()`. - Flush and synchronize the temporary file before replacement where durability is required. - Reject symlinks and non-regular destination files where platform APIs permit. - Do not suppress permission errors. Fail closed with a clear error if secure storage cannot be established. - Verify the final file owner and permissions after writing. - Consider separating the long-lived secret key and cached access token from non-sensitive configuration and using an operating-system credential store where available. A hardened implementation should ensure that sensitive content is never present in a file with process-default or unverified permissions, even temporarily.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (18)

Credential Access

High
Category
Privilege Escalation
Content
---
name: zyt-tts-test
description: Use Chanjing TTS API to convert text to speech by listing voices, creating synthesis tasks, and polling task status. This skill reads app_id and secret_key from ~/.chanjing/credentials.json or $CHANJING_CONFIG_DIR/credentials.json, refreshes access_token for API calls, and returns login guidance when credentials are missing or invalid.
metadata:
  openclaw:
    requires:
Confidence
84% confidence
Finding
The skill description explicitly states it reads app_id and secret_key from a local credentials file and uses them to mint access tokens. Accessing local secrets is sensitive behavior and, without narrow scoping and strong handling guarantees, can enable unintended disclosure or misuse of API credentials.

Credential Access

High
Category
Privilege Escalation
Content
This skill reads credentials from:

- `~/.chanjing/credentials.json`
- or `$CHANJING_CONFIG_DIR/credentials.json`

The credentials file should contain:
Confidence
90% confidence
Finding
This section instructs the skill to read credentials from ~/.chanjing/credentials.json or an environment-controlled directory. Reading authentication material from disk is a real sensitive capability, and the env-controlled alternate path broadens the trust boundary because a manipulated environment can redirect the skill to attacker-chosen files.

Credential Access

High
Category
Privilege Escalation
Content
This skill reads credentials from:

- `~/.chanjing/credentials.json`
- or `$CHANJING_CONFIG_DIR/credentials.json`

The credentials file should contain:
Confidence
90% confidence
Finding
The continued credential-loading guidance reinforces that the skill consumes local secret material from configurable paths. In an agent setting, any workflow that normalizes reading local credentials without strict controls raises the risk of secret harvesting or accidental disclosure through logs, errors, or downstream tool use.

Credential Access

High
Category
Privilege Escalation
Content
## API Notes

### Access Token

Read `app_id` and `secret_key` from the local credentials file. If there is no valid token, request one from:
Confidence
82% confidence
Finding
This section describes obtaining an access token using locally stored app_id and secret_key, which is legitimate for API auth but still a sensitive flow. The danger is not the token exchange itself; it is that the skill operationalizes local secret use and network authentication without describing safeguards for token storage, output redaction, or least privilege.

Credential Access

High
Category
Privilege Escalation
Content
| Code | Description |
|---|---|
| `0` | success |
| `10400` | access token verification failed |
| `40000` | parameter error |
| `50000` | system internal error |
| `51000` | system internal error |
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
| Code | Description |
|---|---|
| `0` | success |
| `10400` | access token verification failed |
| `40000` | parameter error |
| `50000` | system internal error |
| `51000` | system internal error |
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
| Code | Description |
|---|---|
| `0` | success |
| `10400` | access token verification failed |
| `40000` | parameter error |
| `50000` | system internal error |
| `51000` | system internal error |
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# 鉴权:从 CONFIG_DIR/credentials.json 读取 AK/SK
# 实现:AK/SK 校验、Token 校验与刷新;默认不自动打开浏览器,仅返回登录引导信息
import json
import os
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# 鉴权:从 CONFIG_DIR/credentials.json 读取 AK/SK
# 实现:AK/SK 校验、Token 校验与刷新;默认不自动打开浏览器,仅返回登录引导信息
import json
import os
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# 鉴权:从 CONFIG_DIR/credentials.json 读取 AK/SK
# 实现:AK/SK 校验、Token 校验与刷新;默认不自动打开浏览器,仅返回登录引导信息
import json
import os
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# 鉴权:从 CONFIG_DIR/credentials.json 读取 AK/SK
# 实现:AK/SK 校验、Token 校验与刷新;默认不自动打开浏览器,仅返回登录引导信息
import json
import os
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# 鉴权:从 CONFIG_DIR/credentials.json 读取 AK/SK
# 实现:AK/SK 校验、Token 校验与刷新;默认不自动打开浏览器,仅返回登录引导信息
import json
import os
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding
The skill documents capabilities to read environment variables and local files, write configuration files, invoke shell scripts, and make network requests, but it does not declare any explicit tool scope or permission boundaries. That creates an over-privileged execution model where an agent may use more powerful primitives than the user expects, increasing the chance of credential exposure or unintended local side effects.

Session Persistence

Medium
Category
Rogue Agent
Content
- generate Chinese or English speech from text
- list available voices and choose a suitable one
- adjust speech speed
- create a TTS task and poll until completion
- return the remote audio URL and subtitle timestamps from the API result

## How to Use This Skill
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.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
This code writes sensitive credentials and access tokens to a local file and later reuses them, but the only nearby comments are implementation notes rather than user-facing warnings. Under SQP-2 for code files, access to credentials and file writes should have some visible disclosure such as a prompt, log, or explicit warning in documentation.

Tainted flow: 'CONFIG_FILE' from os.environ.get (line 10, credential/environment) → open (file write)

Medium
Category
Data Flow
Content
os.chmod(CONFIG_DIR, 0o700)
    except Exception:
        pass
    with open(CONFIG_FILE, "w", encoding="utf-8") as f:
        json.dump(data, f, indent=2, ensure_ascii=False)
    try:
        os.chmod(CONFIG_FILE, 0o600)
Confidence
65% confidence
Finding
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The function sends app_id and secret_key to a remote API endpoint to obtain an access token, but there is no confirmation prompt, print/log statement, or docstring warning users that local credentials will be transmitted over the network. This is a safety-relevant network operation involving sensitive data and falls within SQP-2.

Natural-Language Policy Violations

Low
Confidence
78% confidence
Finding
The file's human-facing strings and comments are written exclusively in Chinese, including error messages returned to users, with no mechanism offering a language choice. This can violate the language/locale policy criterion when a skill forces a specific language without user opt-in.

Static analysis

No suspicious patterns detected.