Back to skill

Security audit

Chanjing Credentials Guard

Security checks for vulnerabilities and agentic risk

Overview

This skill appears intended to manage Chanjing credentials, but its handling of secrets has enough avoidable exposure risk that users should review it carefully before installing.

Install only if you trust this publisher and are comfortable with Chanjing AK/SK and tokens being stored locally. Before use, avoid setting CHANJING_OPENAPI_BASE_URL or CHANJING_API_BASE unless you fully trust the endpoint, avoid putting real secret keys in shell history or CI logs, and treat any printed access token as sensitive credential material.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/chanjing_get_token.py:22
Finding
Environment-Controlled API Base URL Can Exfiltrate Chanjing Credentials## Vulnerability Details **File Location**: `scripts/chanjing_get_token.py`, lines 22–34, 67–76, and 110–111 **Vulnerability Type**: Unvalidated credential transmission endpoint **Risk Level**: High ### Vulnerable Code ```python def openapi_base_url() -> str: return ( os.environ.get("CHANJING_OPENAPI_BASE_URL") or os.environ.get("CHANJING_API_BASE") or _DEFAULT_OPENAPI_BASE ).rstrip("/") CONFIG_DIR = credentials_config_dir() CONFIG_FILE = CONFIG_DIR / "credentials.json" API_URL = openapi_base_url() + "/open/v1/access_token" ``` ```python def fetch_token(app_id, secret_key): req = urllib.request.Request( API_URL, data=json.dumps({"app_id": app_id, "secret_key": secret_key}).encode("utf-8"), headers={"Content-Type": "application/json"}, method="POST", ) with urllib.request.urlopen(req, timeout=30) as resp: body = json.loads(resp.read().decode("utf-8")) return body ``` ```python try: resp = fetch_token(app_id, secret_key) except Exception as e: print(f"请求 Token 失败: {e}", file=sys.stderr) sys.exit(1) ``` ### Technical Analysis The token client reads `CHANJING_OPENAPI_BASE_URL` or the legacy `CHANJING_API_BASE` directly from the process environment and uses the resulting value as the destination for a request containing both `app_id` and `secret_key`. The implementation does not validate: - That the URL uses HTTPS. - That the destination hostname is `open-api.chanjing.cc`. - That the port is expected. - That the URL does not contain embedded user information. - That redirects remain on the approved host. Although `manifest.yaml` documents a network allowlist, the Python code does not enforce that allowlist itself. Security therefore depends on the runtime sandbox applying the manifest correctly. In an execution environment that does not enforce it, or where network policy ...[truncated 1508 chars]
Remediation
## Remediation Suggestions 1. Remove production endpoint overrides unless custom deployments are an explicit requirement. 2. Parse the URL with `urllib.parse.urlsplit` and require: - Scheme exactly equal to `https`. - Hostname exactly equal to `open-api.chanjing.cc`, or a narrowly defined trusted-host allowlist. - No embedded username or password. - Only an approved port, normally 443. 3. Reject malformed URLs and values containing unexpected path, query, or fragment components. 4. Disable redirects for the credential request or validate every redirect destination against the same HTTPS hostname allowlist. 5. Treat manifest-level network restrictions as defense in depth rather than the only enforcement mechanism. 6. If custom endpoints must remain supported, require explicit user approval and clearly warn that AK/SK will be transmitted to the configured host. 7. Add automated tests proving that HTTP URLs, unapproved hosts, unusual ports, and cross-host redirects are rejected.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/chanjing_config.py:115
Finding
Secret Key Is Accepted Through Exposed Command-Line Arguments## Vulnerability Details **File Location**: `scripts/chanjing_config.py`, lines 115–117 and 124–125; documented in `SKILL.md`, lines 89–94, 124–127, and 190–192 **Vulnerability Type**: Sensitive information exposure through process arguments and shell history **Risk Level**: Medium ### Vulnerable Code ```python parser.add_argument("--ak", help="Access Key (app_id)") parser.add_argument("--sk", help="Secret Key (secret_key)") parser.add_argument("--status", "-s", action="store_true", help="查看配置状态") ``` ```python if args.ak and args.sk: set_credentials(args.ak, args.sk) return ``` The documented workflow explicitly instructs users to invoke the script with the secret as a command-line argument: ```bash python scripts/chanjing_config.py --ak <your_app_id> --sk <your_secret_key> python skills/chanjing-credentials-guard/scripts/chanjing_config.py --ak <your_app_id> --sk <your_secret_key> ``` ### Technical Analysis Command-line arguments are not an appropriate default transport for long-lived secrets. Depending on the platform and execution environment, argument values may be exposed through: - Shell history files. - Process inspection interfaces and process-monitoring tools. - Terminal session recording. - CI/CD command logs. - Agent or orchestration telemetry. - Audit and endpoint-monitoring products. - Wrapper scripts that log complete commands. The Skill correctly tells users not to paste credentials into chat, but the recommended replacement still creates several local disclosure channels. Applying restrictive permissions to `credentials.json` does not protect the secret before it reaches that file. ### Attack Path 1. The victim follows the documented command and supplies the real Secret Key using `--sk`. 2. The shell stores the complete command in its history, or a process-monitoring or automation system captures the argument list. 3. Another local user, administrator, compromi ...[truncated 763 chars]
Remediation
## Remediation Suggestions 1. Make interactive protected input the default: ```python from getpass import getpass secret_key = getpass("Secret Key: ") ``` 2. Accept the App ID interactively or through a non-secret option, while reading the Secret Key from `getpass`, protected stdin, or an operating-system credential store. 3. Remove `--sk` from the primary documented workflow. 4. If backward compatibility requires retaining `--sk`, mark it as unsafe, issue a warning, and recommend immediate shell-history cleanup and key rotation after accidental exposure. 5. Support secure automation through a file descriptor or protected input file with strict ownership and mode checks rather than a command-line value. 6. Ensure error messages, debug logs, and exception handlers never reproduce the supplied secret.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/chanjing_get_token.py:101
Finding
Bearer Access Token Is Printed Directly to Standard Output## Vulnerability Details **File Location**: `scripts/chanjing_get_token.py`, lines 101–103 and 128–130; behavior documented in `SKILL.md`, lines 167–168 **Vulnerability Type**: Sensitive information exposure through standard output **Risk Level**: Medium ### Vulnerable Code ```python if token and expire_in > now + BUFFER_SECONDS: print(token) return 0 ``` ```python data["access_token"] = new_token data["expire_in"] = new_expire write_config(data) print(new_token) return 0 ``` ### Technical Analysis The script emits the complete bearer access token to standard output whenever it returns a cached token or successfully obtains a new one. Standard output is frequently captured by: - AI-agent and Skill execution frameworks. - CI/CD systems. - Terminal recorders. - Shell command substitution and wrapper scripts. - Centralized logging and observability platforms. - Support diagnostics and execution transcripts. A bearer token generally grants access based on possession alone. Printing it by default expands its exposure from the protected credential file to every system that records command output. This undermines the otherwise restrictive `0600` file permission used for persisted credentials. ### Attack Path 1. The victim or an automated agent runs `scripts/chanjing_get_token.py`. 2. The script prints the valid access token to stdout. 3. The execution framework, terminal recorder, CI service, or logging wrapper stores the output. 4. An unauthorized user gains read access to the captured output. 5. The attacker extracts and reuses the bearer token before it expires. ### Impact Assessment The attacker can perform Chanjing API operations authorized by the token until it expires or is revoked. The exact scope is limited to the permissions represented by that token. This does not directly disclose the underlying Secret Key, but it enables temporary account or API impersonation. Exposure ...[truncated 118 chars]
Remediation
## Remediation Suggestions 1. Do not print the token by default. Return only a success or status message. 2. Keep the token in the protected credential file or an operating-system credential store and let authorized clients read it through a controlled interface. 3. If machine-readable token output is essential, require an explicit option such as `--print-token` and display a clear warning that output must not be logged. 4. Prefer passing tokens to child processes through a protected pipe or inherited file descriptor rather than terminal-visible stdout. 5. Configure Skill runners and CI systems to redact token-shaped output as defense in depth. 6. Document token revocation and rotation procedures for users who accidentally expose command output.
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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (30)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill claims to operate via local commands only, yet it instructs opening a remote login page and interacting with a remote service. That creates a trust-boundary expansion not captured by the description, increasing the chance that users trigger external actions and credential workflows they did not expect from a supposedly local-only helper.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill claims to operate via local commands only, yet it instructs opening a remote login page and interacting with a remote service. That creates a trust-boundary expansion not captured by the description, increasing the chance that users trigger external actions and credential workflows they did not expect from a supposedly local-only helper.

Credential Access

High
Category
Privilege Escalation
Content
description: >-
  Guide users to configure local Chanjing credentials safely via local
  commands only, and validate local token status when needed.
credential: credentials.json (app_id/secret_key; access_token persisted on disk)
openclaw_primary_env: false
environment: CHANJING_OPENAPI_CREDENTIALS_DIR, CHANJING_OPENAPI_BASE_URL
legacy_environment: CHANJING_CONFIG_DIR, CHANJING_API_BASE
Confidence
95% confidence
Finding
The skill is explicitly designed to access and persist credentials, including long-lived AK/SK and a usable access token on disk. Storing and handling active credentials is inherently sensitive, and if the file permissions, path controls, or output handling are weak, an attacker or adjacent process could obtain credentials and impersonate the user against the Chanjing API.

Credential Access

High
Category
Privilege Escalation
Content
AK/SK and Token are read from the **same config file**. Path and format follow the script **`scripts/chanjing_config.py`** in this skill.

- **Path**: `~/.chanjing/credentials.json`(目录由 **`CHANJING_OPENAPI_CREDENTIALS_DIR`** 覆盖,兼容 **`CHANJING_CONFIG_DIR`**)
- **Format**:
```json
{
Confidence
96% confidence
Finding
The documentation specifies a plaintext-style credentials file containing app_id, secret_key, and access_token in a predictable path under the user's home directory, overridable by environment variables. Predictable credential storage combined with token persistence increases theft risk from local malware, misconfigured permissions, backups, logs, or malicious path redirection via environment overrides.

Credential Access

High
Category
Privilege Escalation
Content
### Step 1: Check if already configured

Check if local AK/SK already exists (read `~/.chanjing/credentials.json` for non-empty `app_id` and `secret_key`, or run `python skills/chanjing-credentials-guard/scripts/chanjing_config.py --status`).

### Step 2: Branch on result
Confidence
91% confidence
Finding
The skill instructs reading the credential file to determine whether AK/SK are configured, reinforcing routine access to highly sensitive local secrets. In context, the skill is a credential-management helper, so some secret access is expected, but the danger is increased because related workflow steps also fetch, persist, and expose tokens, broadening the blast radius of any misuse or compromise.

Credential Access

High
Category
Privilege Escalation
Content
persistAccessTokenOnDisk: true
  primaryEnvIntentionallyOmitted: true
  doNotCommitToVcs:
    - credentials.json

clientPermissions:
  network:
Confidence
88% confidence
Finding
The manifest explicitly enables persistAccessTokenOnDisk: true, meaning access tokens are stored locally in credentials.json. Persisting bearer tokens on disk increases the chance of token theft through local compromise, accidental backup/sync, or overly broad filesystem permissions, especially because the same manifest also grants read/write access to the credentials location.

Credential Access

High
Category
Privilege Escalation
Content
read:
      - "${CHANJING_OPENAPI_CREDENTIALS_DIR or CHANJING_CONFIG_DIR or ~/.chanjing}/credentials.json"
    write:
      - "${CHANJING_OPENAPI_CREDENTIALS_DIR or CHANJING_CONFIG_DIR or ~/.chanjing}/credentials.json"
      - "${CHANJING_OPENAPI_CREDENTIALS_DIR or CHANJING_CONFIG_DIR or ~/.chanjing}/"
  browser:
    mayOpenForAuth: true
Confidence
80% confidence
Finding
The manifest grants write access not only to credentials.json but to the entire credentials directory. Directory-level write permission creates unnecessary opportunity to alter, replace, or add files in the credential store, which can facilitate credential tampering, persistence, or abuse if the skill implementation is compromised or behaves unexpectedly.

Credential Access

High
Category
Privilege Escalation
Content
## API (chanjing-openapi.yaml)

### Get Access Token

| Item | Value |
|------|--------|
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
AK/SK are read from a config file. Path and format follow **`scripts/chanjing_config.py`** (see `CONFIG_DIR`, `CONFIG_FILE`, and `read_config()` in that script).

File path: `~/.chanjing/credentials.json` (default; override with env `CHANJING_CONFIG_DIR`)

```json
{
Confidence
87% confidence
Finding
This line discloses the exact default credential file location and confirms that AK/SK are read from it, which materially lowers the effort for credential discovery by malware, a local attacker, or unsafe automation. In a credential-management skill this context makes the reference relevant, but still dangerous because it centralizes secret location details without paired safeguards.

Credential Access

High
Category
Privilege Escalation
Content
#!/usr/bin/env python3
"""
获取有效的 access_token。
AK/SK 从与 chanjing_config.py 相同的配置文件中读取(CONFIG_DIR/credentials.json,见 chanjing_config.py)。
若无 AK/SK 则输出引导信息并退出;若 Token 过期则自动申请并保存。
用法: python chanjing_get_token.py
输出: 成功时打印 access_token 到 stdout;失败时打印错误到 stderr 并 exit 1
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
#!/usr/bin/env python3
"""
获取有效的 access_token。
AK/SK 从与 chanjing_config.py 相同的配置文件中读取(CONFIG_DIR/credentials.json,见 chanjing_config.py)。
若无 AK/SK 则输出引导信息并退出;若 Token 过期则自动申请并保存。
用法: python chanjing_get_token.py
输出: 成功时打印 access_token 到 stdout;失败时打印错误到 stderr 并 exit 1
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
#!/usr/bin/env python3
"""
获取有效的 access_token。
AK/SK 从与 chanjing_config.py 相同的配置文件中读取(CONFIG_DIR/credentials.json,见 chanjing_config.py)。
若无 AK/SK 则输出引导信息并退出;若 Token 过期则自动申请并保存。
用法: python chanjing_get_token.py
输出: 成功时打印 access_token 到 stdout;失败时打印错误到 stderr 并 exit 1
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
#!/usr/bin/env python3
"""
获取有效的 access_token。
AK/SK 从与 chanjing_config.py 相同的配置文件中读取(CONFIG_DIR/credentials.json,见 chanjing_config.py)。
若无 AK/SK 则输出引导信息并退出;若 Token 过期则自动申请并保存。
用法: python chanjing_get_token.py
输出: 成功时打印 access_token 到 stdout;失败时打印错误到 stderr 并 exit 1
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
#!/usr/bin/env python3
"""
获取有效的 access_token。
AK/SK 从与 chanjing_config.py 相同的配置文件中读取(CONFIG_DIR/credentials.json,见 chanjing_config.py)。
若无 AK/SK 则输出引导信息并退出;若 Token 过期则自动申请并保存。
用法: python chanjing_get_token.py
输出: 成功时打印 access_token 到 stdout;失败时打印错误到 stderr 并 exit 1
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
#!/usr/bin/env python3
"""
获取有效的 access_token。
AK/SK 从与 chanjing_config.py 相同的配置文件中读取(CONFIG_DIR/credentials.json,见 chanjing_config.py)。
若无 AK/SK 则输出引导信息并退出;若 Token 过期则自动申请并保存。
用法: python chanjing_get_token.py
输出: 成功时打印 access_token 到 stdout;失败时打印错误到 stderr 并 exit 1
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
#!/usr/bin/env python3
"""
获取有效的 access_token。
AK/SK 从与 chanjing_config.py 相同的配置文件中读取(CONFIG_DIR/credentials.json,见 chanjing_config.py)。
若无 AK/SK 则输出引导信息并退出;若 Token 过期则自动申请并保存。
用法: python chanjing_get_token.py
输出: 成功时打印 access_token 到 stdout;失败时打印错误到 stderr 并 exit 1
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
#!/usr/bin/env python3
"""
获取有效的 access_token。
AK/SK 从与 chanjing_config.py 相同的配置文件中读取(CONFIG_DIR/credentials.json,见 chanjing_config.py)。
若无 AK/SK 则输出引导信息并退出;若 Token 过期则自动申请并保存。
用法: python chanjing_get_token.py
输出: 成功时打印 access_token 到 stdout;失败时打印错误到 stderr 并 exit 1
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The script performs outbound network access to request a fresh access token from a remote API, even though the skill metadata says credential handling should occur via local commands only. This mismatch matters because users and higher-level tooling may trust the skill to stay local, while it actually transmits stored credentials off-host and changes local state by refreshing and persisting tokens.

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill documents capabilities that include environment access, file read/write, shell execution, and outbound network activity, but it does not declare an explicit tool scope such as permissions or allowed-tools. That weakens containment and reviewability because consumers cannot easily tell what actions the skill may invoke, especially around credential files and token retrieval.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
The file mixes English and Chinese, but key instructional content begins with Chinese-only sections such as '功能说明' and operational guidance in Chinese. Under the policy, forcing a specific language without user opt-in can be a natural-language policy violation unless the locale constraint is explicitly documented and justified.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
2. **Require local setup command** after the user obtains keys:
   - Show command only; user runs it locally in terminal.
3. **Do not request secrets in chat**:
   - Never ask user to paste AK/SK in conversation.
   - Never echo or store AK/SK in chat summaries.
4. **After setting**:
   - Ask user to run status check and then proceed to target action.
Confidence
80% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
python skills/chanjing-credentials-guard/scripts/chanjing_config.py --ak <your_app_id> --sk <your_secret_key>
   ```
4. **Secret handling rule**:
   - Do not ask user to paste AK/SK in chat.
   - If user shares secret in chat anyway, remind them to rotate keys and continue with local-command-only flow.
5. **After setting**:
   - Run status check:
Confidence
80% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
- This skill only handles **local credential guidance**.
- It does not require install hooks or elevated/system-wide privileges.
- It should not automatically execute unrelated skills.
- It should not accept AK/SK via chat content.

## Shell Config
Confidence
80% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The document instructs users to store long-lived AK/SK secrets and optional access tokens in a local JSON file but does not warn that this is plaintext credential storage or recommend file permission hardening. This increases the chance that secrets are exposed through local compromise, backups, shared home directories, or accidental disclosure, especially because the exact path and schema are documented.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The module documentation describes behavior in a way that understates what the script really does: it not only retrieves a token but automatically requests a new one from a remote service and saves it locally. Security-relevant documentation mismatches are dangerous because reviewers, users, and automated policy systems may approve or invoke the script under false assumptions about data flow and side effects.

Static analysis

No suspicious patterns detected.