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. ]]>
