T09 · Insecure Skill Coding Practices
- Location
scripts/fetch_wechat_article.py:219- Finding
Unrestricted URL Fetching Enables Server-Side Request Forgery
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill has a clear WeChat-article-saving purpose, but its code can fetch any user-supplied URL instead of enforcing the documented WeChat-only scope.
Review before installing. Use it only with trusted WeChat article links and run it in an environment whose outbound network access is constrained, because the code does not enforce the WeChat-only destination it documents. Expect Markdown files to be written locally, and do not rely on the --images option to save images locally.
scripts/fetch_wechat_article.py:219Unrestricted URL Fetching Enables Server-Side Request Forgery
The skill documentation indicates capabilities involving outbound network access and local file writes, but it does not declare any tool scope such as permissions or allowed-tools. This creates an authorization and transparency gap: an agent or reviewer cannot easily constrain or audit what the skill is allowed to access, increasing the risk of unintended network fetches or writes beyond user expectations.
The HTTP headers hard-code Accept-Language: zh-CN,zh;q=0.9,en;q=0.8, which imposes a specific language/locale preference for all requests. This is a natural-language policy concern because the skill does not offer user opt-in or explain why a Chinese locale is required.
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.
filename = f"{safe_title}.md"
filepath = os.path.join(output_dir, filename)
with open(filepath, 'w', encoding='utf-8') as f:
f.write(markdown)
print(f'已保存: {filepath}')
The skill is designed to fetch remote article content and save it locally, but the description does not clearly warn users that local storage occurs by default. This can lead to unintentional persistence of content on disk, which is a privacy and user-expectation issue, especially on shared machines or when handling sensitive article URLs.
The module docstring and CLI help claim the tool supports downloading images locally, and fetch_article accepts a save_images parameter for that purpose. However, the function never uses save_images; it only preserves remote image URLs in generated Markdown and writes a single .md file.
The --images argument is described as 下载图片到本地, which tells users the program will fetch and save article images locally. In reality, args.images is merely passed through to fetch_article, where it is ignored and no image download logic exists.
No suspicious patterns detected.