Back to skill

Security audit

Test Import

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it says by publishing local skill files to ClawHub, but it ships a hardcoded publishing token and uploads selected local files without strong user review controls.

Review the target directory carefully before using this skill, because it uploads matching source and text files to ClawHub and may publish them publicly or under the configured account. Do not install or run this version with the embedded token present; the publisher should revoke that token and replace it with user-provided credentials plus a dry-run or confirmation step.

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

Error
Location
publish.py:11
Finding
Hardcoded ClawHub Bearer Token Exposes Publishing Credentials<![CDATA[ ## Vulnerability Details **File Location**: `publish.py:11`, with credential use at `publish.py:18-21` and `publish.py:70-74` **Vulnerability Type**: Hardcoded authentication secret **Risk Level**: High ### Vulnerable Code ```python TOKEN = "clh_GKYQNYsiccGeacf6up29a0XJdyFdyPOCzzLWaWukx3k" ``` The token is used to authenticate requests that acquire an upload URL: ```python resp = requests.post( "https://clawhub.ai/api/cli/upload-url", headers={"Authorization": f"Bearer {TOKEN}"}, json={"filename": filename, "contentType": content_type} ) ``` It is also used to publish Skill files: ```python resp = requests.post( API_URL, headers={"Authorization": f"Bearer {TOKEN}"}, data={"payload": json.dumps(payload)}, files=file_data ) ``` ### Technical Analysis The source code contains a plaintext bearer token that is distributed with the Skill package. Bearer tokens grant access based solely on possession, so any party able to read the package can extract and reuse this credential without knowing a password. The code actively supplies the token to ClawHub endpoints for upload and publication operations, demonstrating that it is intended as an authentication credential rather than an unused example value. Its current validity and exact server-side scope cannot be confirmed through static analysis. Nevertheless, embedding it in distributable source code eliminates effective control over who can possess it and violates least-privilege credential-management practices. Uploading local Skill files to ClawHub is consistent with the documented functionality and is not, by itself, covert exfiltration. The vulnerability is the globally exposed credential used to authorize that operation. ### Attack Path 1. An attacker downloads or otherwise obtains a copy of the Skill package. 2. The attacker opens `publish.py` and extracts the value assigned to `TOKEN`. 3. The attacker sends requests to the ClawHub API with the header: ```http ...[truncated 1044 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Revoke the exposed token immediately** - Treat the credential as compromised because it has been committed to and distributed with the project. - Review relevant ClawHub audit logs for unauthorized upload or publication activity. 2. **Rotate the credential** - Generate a replacement token after revocation. - Grant only the minimum permissions required to publish Skills. - Prefer short-lived, per-user, or per-project credentials where supported. 3. **Remove credentials from source code** - Load the token from a protected environment variable or credential store: ```python TOKEN = os.environ.get("CLAWHUB_TOKEN") if not TOKEN: raise RuntimeError("CLAWHUB_TOKEN is required") ``` - Do not provide an embedded fallback token. 4. **Prevent accidental disclosure** - Add secret scanning to pre-commit checks and CI release pipelines. - Block commits containing token patterns. - Ensure local credential files are excluded through `.gitignore` and are never included in published Skill directories. 5. **Improve request handling** - Use explicit request timeouts. - Call `raise_for_status()` before trusting API responses. - Avoid returning raw server response bodies when they might contain sensitive operational details. 6. **Review publication inputs** - Require users to confirm the selected directory and file list before upload. - Consider an explicit manifest or allowlist so unrelated `.md`, `.py`, `.js`, `.json`, or `.txt` files containing secrets are not unintentionally published. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (9)

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The skill explicitly instructs users to publish a local skill directory to an external service, but the documentation does not warn that local contents will be transmitted or encourage users to review included files first. In a skill-publishing context, this can lead to accidental disclosure of secrets, private prompts, test data, or other sensitive files bundled in the target directory.

Natural-Language Policy Violations

Medium
Confidence
86% confidence
Finding
The natural-language instructions and examples are presented in Chinese, including parameter examples and descriptive text, with no indication that the user may choose another language or that the skill is intentionally region-specific. Under the stated policy, forcing a specific language without opt-in is a natural-language policy concern.

External Transmission

Medium
Category
Data Exfiltration
Content
def upload_file(filename, content_type="text/plain"):
    """获取上传URL并上传文件"""
    resp = requests.post(
        "https://clawhub.ai/api/cli/upload-url",
        headers={"Authorization": f"Bearer {TOKEN}"},
        json={"filename": filename, "contentType": content_type}
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
def upload_file(filename, content_type="text/plain"):
    """获取上传URL并上传文件"""
    resp = requests.post(
        "https://clawhub.ai/api/cli/upload-url",
        headers={"Authorization": f"Bearer {TOKEN}"},
        json={"filename": filename, "contentType": content_type}
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Tainted flow: 'upload_url' from requests.post (line 23, network input) → requests.put (network output)

Medium
Category
Data Flow
Content
if upload_url:
        # 上传文件内容
        requests.put(upload_url, data=content, headers={"Content-Type": content_type})
    
    return True
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
96% confidence
Finding
The script reads local files from the provided skill directory and uploads them to a remote service without any explicit user-facing warning about what content will leave the machine. In a skill/publishing context, this can lead to unintended disclosure of source code, embedded secrets, or sensitive documentation if users point the tool at the wrong directory or do not understand that all matching files are transmitted.

Natural-Language Policy Violations

Low
Confidence
94% confidence
Finding
The comment on L06 is written only in Chinese, which reflects a language-specific instruction in the file without offering any language choice or justification. The policy explicitly calls for flagging language or locale constraints when they force a specific language without opt-in.

Natural-Language Policy Violations

Low
Confidence
82% confidence
Finding
The `reasoning` field and duplicated `raw_prediction.reasoning` text are written only in Chinese, with no indication that language choice is optional or that the skill is region-specific. This can violate a language/locale policy when a skill or its metadata implicitly enforces one language without user opt-in.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
The file's human-facing description and CLI help text are written in Chinese, which imposes a specific language on users of the skill without any opt-in or explanation that the tool is intended only for a Chinese-speaking audience. This matches the policy category for language or locale constraints expressed in natural-language content.

Static analysis

No suspicious patterns detected.