T09 · Insecure Skill Coding Practices
Error
- Location
- fetch.sh:43
- Finding
- Hard-Coded Administrative API Token in Executable Script<![CDATA[ ## Vulnerability Details **File Location**: `fetch.sh`, lines 43-45 and 81-88 **Vulnerability Type**: Hard-coded authentication credential **Risk Level**: High ### Vulnerable Code ```bash # 从 TOOLS.md 读取 token(如果存在) TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2Y3MzBlZWUtODU3YS00MWRlLTljM2EtNTMxODY5NDU0OTE5IiwiSUQiOjUxLCJVc2VybmFtZSI6ImxhYmlkIiwiTmlja05hbWUiOiJsYWJpZCIsIkF1dGhvcml0eUlkIjoxMDEsIkJ1ZmZlclRpbWUiOjg2NDAwLCJpc3MiOiJxbVBsdXMiLCJhdWQiOlsiR1ZBIl0sImV4cCI6MTc3MzI5NzIwNiwibmJmIjoxNzcyNjkyNDA2fQ.mt1dR1Qom9HJ6WIfWeGgKm0dKa_Ekoe6HWiO0uGwfgo" ``` The credential is subsequently sent to an administrative API: ```bash # 调用 ChainThink API RESPONSE=$(curl -s 'https://api-v2.chainthink.cn/ccs/v1/admin/content/publish' \ -H 'Content-Type: application/json' \ -H 'X-App-Id: 101' \ -H "x-token: $TOKEN" \ -H 'x-user-id: 51' \ --data-raw "$PAYLOAD") ``` ### Technical Analysis The script embeds a complete JWT directly in source code and uses it to authenticate to the ChainThink administrative content-publishing API. Any person or process able to obtain the project files can extract the token without needing access to a protected credential store. The token also contains decodable account metadata, including a user ID, username, UUID, and authority identifier. JWT encoding does not provide confidentiality. Although the credential may expire, source control history, copied packages, build artifacts, and cached distributions can continue to expose it. If the token is refreshed by replacing it in source code, the same flaw will recur. This behavior also contradicts `SKILL.md`, which says that the token must be supplied through `TOOLS.md`. The implementation never reads that file and instead always uses the embedded credential. ### Attack Path 1. An attacker downloads, receives, or otherwise reads the skill package. 2. The attacker opens `fetch.sh` and extracts the JWT assigned to `TOKEN`. 3. The attacker decodes the JWT to identify ...[truncated 1104 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Revoke or rotate the exposed JWT immediately, even if it appears to have expired. 2. Remove the credential from the current source tree and all accessible repository history, release archives, logs, and build artifacts. 3. Load the token from a protected environment variable or dedicated secret manager: ```bash : "${CHAINTHINK_TOKEN:?CHAINTHINK_TOKEN must be configured}" TOKEN="$CHAINTHINK_TOKEN" ``` 4. Never store live credentials in `SKILL.md`, `TOOLS.md`, source-controlled configuration, examples, or shell scripts. 5. Restrict the replacement credential to the single required publishing operation and the minimum required account scope. 6. Add automated secret scanning to commits and release pipelines. 7. Avoid printing the token or verbose HTTP request headers to logs. 8. Implement server-side token rotation, short expiration, revocation, and auditing for unusual publishing activity. 9. Review ChainThink audit logs for unauthorized requests made using the exposed account. ]]>
