Back to skill

Security audit

Chanjing Ai Creation

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its stated Chanjing API purpose, but it gives credentialed network calls and downloads broader control than the manifest safely scopes.

Review before installing. Use this only in a private, trusted environment, keep CHANJING_OPENAPI_BASE_URL and CHANJING_API_BASE unset unless you fully trust the endpoint, protect ~/.chanjing/credentials.json, and avoid invoking download_result.py with untrusted URLs or custom output paths until the downloader is constrained.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/_auth.py:20
Finding

Credentials and Access Tokens Can Be Transmitted to an Unrestricted Environment-Controlled Endpoint

Content
View full analysis
str: return ( os.environ.get("CHANJING_OPENAPI_BASE_URL") or os.environ.get("CHANJING_API_BASE") or _DEFAULT_OPENAPI_BASE ).rstrip("/") ``` ```python url = API_BASE + "/open/v1/access_token" req = urllib.request.Request( url, data=json.dumps({"app_id": app_id, "secret_key": secret_key}).encode("utf-8"), headers={"Content-Type": "application/json"}, method="POST", ) try: with urllib.request.urlopen(req, timeout=30) as resp: body = json.loads(resp.read().decode("utf-8")) ``` The same unrestricted base URL is used when sending access tokens: ```python API_BASE = (__import__("os").environ.get("CHANJING_OPENAPI_BASE_URL") or __import__("os").environ.get("CHANJING_API_BASE") or "https://open-api.chanjing.cc").rstrip("/") ``` ```python def api_get(token, path, query=None): query = query or {} suffix = "" if query: suffix = "?" + urllib.parse.urlencode(query, doseq=True) req = urllib.request.Request( f"{API_BASE}{path}{suffix}", headers={"access_token": token}, method="GET", ) with urllib.request.urlopen(req, timeout=30) as resp: body = json.loads(resp.read().decode("utf-8")) ``` ```python def api_post(token, path, payload): req = urllib.request.Request( f"{API_BASE}{path}", data=json.dumps(payload).encode("utf-8"), headers={"access_token": token, "Content-Type": "application/json"}, method="POST", ) with urllib.request.urlopen(req, timeout=30) as resp: body = json.loads(resp.read().decode("utf-8")) ``` ### Technical Analysis The manifest declares `open-api.chanjing.cc` as an allowed network host, but the implementatio ...[truncated 2087 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/download_result.py:32
Finding

Downloader Permits Arbitrary URL Fetching and Arbitrary File Overwrite

Content
View full analysis
argparse.Namespace: parser = argparse.ArgumentParser(description="下载蝉镜 AI 创作生成结果到本地目录") parser.add_argument("--url", required=True, help="图片或视频输出地址") parser.add_argument( "--output", help="输出文件路径;默认保存到 outputs/ai-creation/<文件名>", ) return parser.parse_args() ``` ```python def main() -> None: args = parse_args() default_dir = Path("outputs") / "ai-creation" output_path = Path(args.output) if args.output else default_dir / infer_filename(args.url) output_path.parent.mkdir(parents=True, exist_ok=True) req = urllib.request.Request( args.url, headers={"User-Agent": "chanjing-ai-creation-downloader"}, method="GET", ) try: with urllib.request.urlopen(req, timeout=120) as resp, open(output_path, "wb") as handle: handle.write(resp.read()) ``` ### Technical Analysis The downloader accepts any URL supplied through `--url`. It does not require HTTPS, restrict destination hosts, reject local or private network addresses, or validate redirect destinations. `urllib.request.urlopen` follows HTTP redirects by default, so an initially trusted-looking URL can redirect to an internal or otherwise disallowed destination. This creates a server-side request forgery-style capability in environments where an Agent can be induced to invoke the downloader with untrusted input. The request does not include the Chanjing access token, but it can still reach services available from the host's network context. The `--output` argument is converted directly into a `Path`. There is no containment check against the documented `outputs/ai-creation/` directory. The destination is opened with mode `wb`, which trunca ...[truncated 1694 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/_auth.py:66
Finding

Credential File Persistence Does Not Enforce Restrictive Permissions or Atomic Writes

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (38)

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

The skill is designed to read and write app_id, secret_key, and access_token to a local credentials.json file. Handling long-lived secrets on disk materially increases exposure through local compromise, backups, sync tools, permissive file permissions, or accidental disclosure by adjacent tools.

Content

Scanner excerpt · SKILL.md (reported line 6)May include surrounding context.

md
description: >-
  Chanjing AI creation Open API client: submit image/video tasks, poll task
  status, list and get tasks, and optionally download outputs when the user runs
  download_result.py. Reads and writes local credentials.json; calls
  open-api.chanjing.cc.
credential: credentials.json (read/write app_id, secret_key, access_token on disk)
openclaw_primary_env: false

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

The declared credential storage behavior confirms persistent local storage of sensitive authentication material. Because the skill also performs network access, compromise of the local credential file could enable unauthorized API use and account abuse beyond the immediate session.

Content

Scanner excerpt · SKILL.md (reported line 8)May include surrounding context.

md
status, list and get tasks, and optionally download outputs when the user runs
  download_result.py. Reads and writes local credentials.json; calls
  open-api.chanjing.cc.
credential: credentials.json (read/write app_id, secret_key, access_token on disk)
openclaw_primary_env: false
environment: CHANJING_OPENAPI_CREDENTIALS_DIR, CHANJING_OPENAPI_BASE_URL
legacy_environment: CHANJING_CONFIG_DIR, CHANJING_API_BASE

Credential Access

High
Category
Privilege Escalation
Confidence
94% confidence
Finding

The operational description again states that the workflow requires reading and writing local credentials.json. Repeated dependence on plaintext credential persistence broadens the attack surface because any other local process, user, or backup mechanism with access to that file may obtain reusable secrets.

Content

Scanner excerpt · SKILL.md (reported line 21)May include surrounding context.

md
## 功能说明

调用蝉镜 **AI 创作** Open API:**提交任务**、**轮询状态**、**列表与单条查询**;仅在用户明确要求时用 `download_result.py` **可选下载**输出。需**读写**本地 `credentials.json` 并访问 Open API。跨模型文生图/视频等由 `submit_task.py` 参数与透传体决定。本 skill 脚本**不**依赖 ffmpeg/ffprobe。

## 运行依赖

Credential Access

High
Category
Privilege Escalation
Confidence
94% confidence
Finding

This finding confirms that core task submission and polling depend on local credential file access. In context, the skill's normal operation makes credential exposure part of the trusted path, so compromise of the host or workspace can translate directly into API impersonation.

Content

Scanner excerpt · SKILL.md (reported line 53)May include surrounding context.

md
* **轮询**异步结果直至完成(`poll_task.py`)
* 仅在用户明确要求时**下载**输出(`download_result.py`)

上述流程依赖读写本地 `credentials.json` 并调用 `open-api.chanjing.cc`。

如果需求更接近“文生数字人”,优先使用 `chanjing-text-to-digital-person`。  
如果需求更接近“已有数字人视频合成”,优先使用 `chanjing-video-compose`。

Credential Access

High
Category
Privilege Escalation
Confidence
96% confidence
Finding

The skill specifies a shared credential path under ~/.chanjing/credentials.json, which can make secrets discoverable to other tools or users depending on host configuration. Standardized, predictable secret locations are easier to target during local compromise and increase blast radius across related skills sharing the same file.

Content

Scanner excerpt · SKILL.md (reported line 64)May include surrounding context.

md
本 Skill 与 guard 共用:

* `~/.chanjing/credentials.json`
* `https://open-api.chanjing.cc`

无凭证时,脚本会自动打开蝉镜登录页,并提示配置命令。

Credential Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

The documentation narrows runtime scope, but it still confirms direct access to local credentials and remote API endpoints as intended behavior. Even though the skill avoids automatic downloads, the combination of credential handling and network use remains security-sensitive because stolen tokens can be used independently of this skill.

Content

Scanner excerpt · SKILL.md (reported line 73)May include surrounding context.

md
与 **Purpose / Credentials / Persistence**、**`download_result.py`** 信任边界相关的逐项说明见 **`manifest.yaml`**。

**运行时范围**:本 Skill 的说明与脚本仅服务于已声明用途——读取本地 **`credentials.json`**、调用蝉镜 **Open API** 端点;**不**在轮询或查询成功时自动落盘生成物,**仅**在用户显式执行 **`download_result.py`** 时下载资源。

**`_auth.py` 与仓库布局**:鉴权辅助可能打开系统浏览器,或按相对路径调用同仓库下的 **`chanjing-credentials-guard`** 脚本(例如 `open_login_page.py`)。这假设当前工作区为 **chan-skills 式多 Skill 目录结构**,或已单独安装并具备等效路径的 guard skill;否则将回退为仅打开登录页 URL。

Credential Access

High
Category
Privilege Escalation
Confidence
97% confidence
Finding

This section explicitly documents storing access_token on disk and acknowledges an expanded leakage surface on shared or backed-up systems. That is a real security risk, not merely informational, because possession of the token may permit unauthorized access to the API until rotation or expiry.

Content

Scanner excerpt · SKILL.md (reported line 77)May include surrounding context.

md
**`_auth.py` 与仓库布局**:鉴权辅助可能打开系统浏览器,或按相对路径调用同仓库下的 **`chanjing-credentials-guard`** 脚本(例如 `open_login_page.py`)。这假设当前工作区为 **chan-skills 式多 Skill 目录结构**,或已单独安装并具备等效路径的 guard skill;否则将回退为仅打开登录页 URL。

**敏感数据与持久化**:预期仅处理 **`credentials.json`** 中的 `app_id`、`secret_key`、`access_token`(及与 token 生命周期相关的字段,见 `manifest.yaml`)。将 **`access_token` 写入磁盘** 是有意设计且已文档化,对 API 客户端而言通常可接受;但在**多人共用主机**、**全盘备份/同步到不可信存储**等场景下,磁盘上的 token 会**扩大泄露面**,需按环境自行评估。

## Standard Workflow

Credential Access

High
Category
Privilege Escalation
Confidence
94% confidence
Finding

The script inventory states that _auth.py reads/writes credentials.json and refreshes access_token, confirming active secret management by the skill. Authentication helpers that persist and refresh secrets increase the chance of credential leakage and unauthorized reuse if the host, workspace, or logs are exposed.

Content

Scanner excerpt · SKILL.md (reported line 110)May include surrounding context.

md
| 脚本 | 说明 |
|------|------|
| `_auth.py` | 读写 `credentials.json`、获取或刷新 `access_token` |
| `submit_task.py` | 提交 AI 创作任务,输出 `unique_id` |
| `get_task.py` | 获取单个任务详情 |
| `list_tasks.py` | 列出图片或视频任务 |

Credential Access

High
Category
Privilege Escalation
Confidence
89% confidence
Finding

The manifest explicitly enables persistAccessTokenOnDisk: true, meaning bearer-style access tokens are stored on disk in credentials.json. Persisting active tokens in a workspace-accessible plaintext file increases the chance of token theft by other local processes, accidental inclusion in backups, or later disclosure through unrelated tooling.

Content

Scanner excerpt · manifest.yaml (reported line 68)May include surrounding context.

yaml
persistAccessTokenOnDisk: true
  primaryEnvIntentionallyOmitted: true
  doNotCommitToVcs:
    - credentials.json

clientPermissions:
  network:

Credential Access

High
Category
Privilege Escalation
Confidence
84% confidence
Finding

Granting write access to the credentials.json path creates the ability to modify persisted secrets and tokens, and in this manifest it is paired with access token persistence. While writing refreshed credentials can be legitimate, allowing credential writes in combination with workspace and env-controlled paths raises risk of secret overwrite, insecure storage, or placement in less protected locations.

Content

Scanner excerpt · manifest.yaml (reported line 79)May include surrounding context.

yaml
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"
  browser:
    mayOpenForAuth: true
    documentedHosts:

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 · manifest.yaml (reported line 43)May include surrounding context.

yaml
#!/usr/bin/env python3
# 鉴权:与 chanjing-credentials-guard 使用同一配置文件(CONFIG_DIR/credentials.json)
# 无 AK/SK 时执行 open_login_page.py 打开注册/登录页
import json
import os

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 · manifest.yaml (reported line 50)May include surrounding context.

yaml
#!/usr/bin/env python3
# 鉴权:与 chanjing-credentials-guard 使用同一配置文件(CONFIG_DIR/credentials.json)
# 无 AK/SK 时执行 open_login_page.py 打开注册/登录页
import json
import os

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 · manifest.yaml (reported line 57)May include surrounding context.

yaml
#!/usr/bin/env python3
# 鉴权:与 chanjing-credentials-guard 使用同一配置文件(CONFIG_DIR/credentials.json)
# 无 AK/SK 时执行 open_login_page.py 打开注册/登录页
import json
import os

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 · manifest.yaml (reported line 59)May include surrounding context.

yaml
#!/usr/bin/env python3
# 鉴权:与 chanjing-credentials-guard 使用同一配置文件(CONFIG_DIR/credentials.json)
# 无 AK/SK 时执行 open_login_page.py 打开注册/登录页
import json
import os

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 · manifest.yaml (reported line 77)May include surrounding context.

yaml
#!/usr/bin/env python3
# 鉴权:与 chanjing-credentials-guard 使用同一配置文件(CONFIG_DIR/credentials.json)
# 无 AK/SK 时执行 open_login_page.py 打开注册/登录页
import json
import os

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

md
#!/usr/bin/env python3
# 鉴权:与 chanjing-credentials-guard 使用同一配置文件(CONFIG_DIR/credentials.json)
# 无 AK/SK 时执行 open_login_page.py 打开注册/登录页
import json
import os

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 · scripts/_auth.py (reported line 2)May include surrounding context.

python
#!/usr/bin/env python3
# 鉴权:与 chanjing-credentials-guard 使用同一配置文件(CONFIG_DIR/credentials.json)
# 无 AK/SK 时执行 open_login_page.py 打开注册/登录页
import json
import os

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

Defining credentials.json as the storage location for API secrets and tokens creates a local credential exposure risk when combined with plaintext reads/writes in this module. The skill context makes this more significant because the file is central to auth and likely reused by multiple scripts, so compromise of one local file grants ongoing access to the external API.

Content

Scanner excerpt · scripts/_auth.py (reported line 29)May include surrounding context.

python
CONFIG_DIR = credentials_config_dir()
CONFIG_FILE = CONFIG_DIR / "credentials.json"
API_BASE = openapi_base_url()
BUFFER_SECONDS = 300
LOGIN_URL = "https://www.chanjing.cc/openapi/login"

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill documentation explicitly describes capabilities to read/write local credentials, access environment variables, perform network requests, and invoke scripts, yet it does not declare an explicit tool scope in this file. Missing or deferred permission scoping increases the chance that an agent executes the skill with broader privileges than reviewers or policy systems expect.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
92% confidence
Finding

Persisting app_id, secret_key, and access_token on disk creates session/auth state that survives beyond the immediate run. Persistent authentication state is dangerous because it extends the time window for theft or misuse and may unintentionally propagate through backups, sync services, or shared systems.

Content

Scanner excerpt · SKILL.md (reported line 8)May include surrounding context.

md
status, list and get tasks, and optionally download outputs when the user runs
  download_result.py. Reads and writes local credentials.json; calls
  open-api.chanjing.cc.
credential: credentials.json (read/write app_id, secret_key, access_token on disk)
openclaw_primary_env: false
environment: CHANJING_OPENAPI_CREDENTIALS_DIR, CHANJING_OPENAPI_BASE_URL
legacy_environment: CHANJING_CONFIG_DIR, CHANJING_API_BASE

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The natural-language instructions, usage guidance, and safety notes are predominantly presented in Chinese, which can impose a language constraint on users. The file does not state that the skill is China/Chinese-language specific or provide an opt-in or alternative language path.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The examples say certain phrases 'usually should trigger this skill' but do not define clear boundaries, exclusions, or confirmation requirements. In an agent setting, vague trigger guidance can cause overbroad activation, leading the skill to handle requests involving network calls, task submission, or downloads when the user did not clearly intend to invoke it.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The examples encourage downloading output files locally but provide no warning about destination paths, overwriting behavior, or the trustworthiness of remote URLs. In a skill that can fetch remote content and write to disk, missing safeguards can lead to unintended local file writes, overwrites, or retrieval of unsafe content if the download flow is invoked too broadly.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/_auth.py (reported line 46)May include surrounding context.

python
skills_dir = Path(__file__).resolve().parent.parent.parent
        script = skills_dir / "chanjing-credentials-guard" / "scripts" / "open_login_page.py"
        if script.exists():
            subprocess.run([sys.executable, str(script)], check=False, timeout=5)
        else:
            import webbrowser

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This code writes app_id, secret_key, and later access_token/expiry data to credentials.json without setting restrictive filesystem permissions or warning the user. On multi-user systems or weakly protected environments, local users, malware, backups, or synced folders could expose these long-lived secrets and enable unauthorized API access.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.