T09 · Insecure Skill Coding Practices
- Location
README.md:112- Finding
Potential WeChat Application Credentials Exposed in Documentation
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill appears to perform its stated WeChat draft-deletion task, but it needs review because it includes real-looking credentials and risky installer/dependency behavior around a destructive account operation.
Review before installing. Replace the example credentials with placeholders and rotate them if they might be real, avoid running the installer with elevated privileges, prefer a virtual environment with pinned Python dependencies, and only run deletion commands against Media IDs you have backed up or are certain should be removed.
README.md:112Potential WeChat Application Credentials Exposed in Documentation
install.sh:14Unpinned and Non-Reproducible Python Dependency Installation
package.json:12Unnecessary npm Package with the Same Name as a Python Dependency
install.sh:21System-Wide Mutable Command Link Exceeds Least-Privilege Requirements
The primary description is written entirely in Chinese and presents the skill as intended for Chinese-language use, without indicating any user choice of language or locale. Under the policy, forcing a specific language without opt-in is a natural-language policy violation unless the locale restriction is clearly documented and justified.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
## API文档
### 微信公众号API
- **接口**: `POST https://api.weixin.qq.com/cgi-bin/draft/delete`
- **参数**: `{"media_id": "草稿Media ID"}`
- **响应**: `{"errcode": 0, "errmsg": "ok"}`
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
## API文档
### 微信公众号API
- **接口**: `POST https://api.weixin.qq.com/cgi-bin/draft/delete`
- **参数**: `{"media_id": "草稿Media ID"}`
- **响应**: `{"errcode": 0, "errmsg": "ok"}`
The README contains a concrete AppID and AppSecret in an example shell script, which teaches users to handle secrets unsafely and may expose a real credential if it was copied from an actual account. In a deletion-focused skill, leaked WeChat API credentials are especially dangerous because they can be used to authenticate to the official API and perform unauthorized operations, including destructive draft deletions.
The skill documentation describes capabilities that require environment variable access, file reading, network calls, and shell-based installation, but it does not declare any explicit tool scope or permissions. This creates an under-specified trust boundary where an agent may invoke broader capabilities than a user expects, increasing the risk of unintended secret access or destructive operations.
The installer forcibly creates or overwrites a symlink in /usr/local/bin using ln -sf and suppresses errors, without prompting the user or verifying that the destination is safe to replace. This can unexpectedly clobber an existing command of the same name or create a privileged system-wide change the user did not explicitly approve, which is risky in an installer context.
The script sends the App Secret in the URL query string when requesting an access token. Secrets embedded in URLs can be exposed via logs, shell history, proxy logs, monitoring systems, or error messages, increasing the chance of credential leakage.
def get_access_token(appid: str, secret: str) -> str:
"""获取微信公众号access_token"""
url = f"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={appid}&secret={secret}"
response = requests.get(url)
data = response.json()
The script places the access_token in the request URL query string for the delete operation. Access tokens in URLs may be captured by application logs, reverse proxies, debugging output, or observability tooling, which can allow unauthorized API actions if the token is reused before expiry.
def delete_draft(access_token: str, media_id: str) -> bool:
"""删除单个草稿"""
url = f"https://api.weixin.qq.com/cgi-bin/draft/delete?access_token={access_token}"
data = {
"media_id": media_id
}
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
}
try:
response = requests.post(url, json=data, timeout=10)
result = response.json()
if result.get('errcode') == 0:
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.
}
try:
response = requests.post(url, json=data, timeout=10)
result = response.json()
if result.get('errcode') == 0:
The usage, examples, troubleshooting, and support sections are all presented only in Chinese, with no note that the skill is region- or language-specific. Although the skill is WeChat-related, the README does not clearly document that the locale constraint is intentional and justified, nor does it offer an opt-in language choice.
The natural-language content of the skill is almost entirely in Chinese, including usage instructions, warnings, and setup guidance. Under the policy, a skill that effectively requires a specific language should either offer a language choice or clearly justify the locale restriction; this file does neither.
All user-facing comments and echo messages are in Chinese, and the script provides no option to select another language or locale. This can violate language-choice policy when a skill forces a specific language without user opt-in.
The dependency is specified as requests>=2.25.1, which allows installation of a wide range of versions without guaranteeing a reviewed, fixed release. This weakens supply-chain control and can result in builds pulling different versions over time, including versions with known security issues or behavior changes.
requests>=2.25.1
Because requests is not pinned, it is impossible to verify from this manifest whether the installed version includes fixes for known advisories affecting some releases. In a skill that deletes WeChat drafts and likely performs authenticated API calls, use of a vulnerable requests version could increase risk of credential leakage or insecure request handling depending on the runtime-resolved version.