T09 · Insecure Skill Coding Practices
- Location
scripts/export.py:68- Finding
Unrestricted document-controlled image retrieval enables server-side request forgery
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill mostly performs Feishu document export, but it overstates batch features, asks for broader Drive access than the shipped code needs, and downloads document-supplied image URLs without destination limits.
Review this skill before installing. Use it only with Feishu credentials scoped as narrowly as possible, avoid granting drive:readonly until folder export actually exists, export only documents you trust, and choose an output directory appropriate for sensitive local copies. Be aware that document image links can make the machine running the skill contact arbitrary HTTP(S) URLs.
scripts/export.py:68Unrestricted document-controlled image retrieval enables server-side request forgery
SKILL.md:31Unnecessary Feishu Drive permission requested for unimplemented folder export
requirements.txt:1Open-ended dependency constraints prevent reproducible, reviewed installations
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
headers = {"Content-Type": "application/json; charset=utf-8"}
data = {"app_id": APP_ID, "app_secret": APP_SECRET}
response = requests.post(url, headers=headers, json=data)
result = response.json()
if result.get("code") != 0:
raise Exception(f"获取token失败: {result.get('msg')}")
代码总体方向与声明相近,确实是在导出飞书 docx 到本地 Markdown,并处理图片、本地保存、可选保留 HTML,因此不存在明显的额外越权或无关恶意行为。但声明中的核心能力“批量导出”“支持文件夹/文档链接批量导出”与实际实现不符:main() 中只要 URL 含有“docx/”就走单文档导出,否则直接提示“文件夹批量导出功能正在开发中,目前仅支持单个文档导出”。虽然参数中有 --recursive,但没有任何实际文件夹遍历逻辑。故这是明显的描述能力高于实际代码能力的情况,属于功能性不匹配。
The skill advertises behavior that requires network access, reading credentials from environment variables, and writing files locally, but it declares no explicit tool scope or permissions. This weakens least-privilege controls and can cause an agent to invoke the skill with broader capabilities than the user expects, increasing the risk of unauthorized network requests or filesystem writes.
The skill description does not clearly warn that it will persist exported document contents and downloaded images to local storage. Because the content may include sensitive internal documents, users may trigger the skill without realizing it creates local copies, which increases the risk of unintended data retention, exposure through backups/sync tools, or writing into unsafe locations.
This markdown file includes steps for configuring application credentials, including an app secret, but does not warn users that the secret is sensitive or should be protected from shell history, screenshots, shared terminals, or committing to files. Because markdown files should disclose behaviors affecting privacy or system integrity, the omission is a meaningful safety gap.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
headers = {"Content-Type": "application/json; charset=utf-8"}
data = {"app_id": APP_ID, "app_secret": APP_SECRET}
response = requests.post(url, headers=headers, json=data)
result = response.json()
if result.get("code") != 0:
raise Exception(f"获取token失败: {result.get('msg')}")
The tool saves document contents and remotely referenced images to local disk automatically, but it does not clearly warn users that potentially sensitive document data and linked assets will be persisted. In an agent/skill context, this can lead to unintended retention of confidential information on shared machines or workspaces.
The skill description says it supports batch export from specified folders or document links, but the code only handles URLs containing "docx/" as a single document. For non-document URLs, it prints that folder batch export is still under development, which directly falls short of the manifest's stated behavior.
This file contains user-facing natural-language content that assumes a single language/locale for all users. Under the policy, forcing a specific language without user opt-in can be a natural-language policy violation unless the locale constraint is explicitly justified.
This file presents all user-facing natural-language content exclusively in Chinese, which can amount to a language/locale policy issue when no user opt-in or documented regional scope is provided. The content does not state that the skill or offering is limited to a Chinese-speaking audience or a China-specific compliance context.
The dependency is specified with a lower bound only (requests>=2.31.0), which makes builds non-reproducible and allows future installs to pull different versions than were tested. In a document-export skill that performs network requests, this increases supply-chain and stability risk and makes it impossible to verify whether a vulnerable or incompatible release is installed.
requests>=2.31.0
markdownify>=0.11.6
requests has known advisories, and because the manifest does not pin a version, there is no assurance that deployments will avoid affected releases. In this skill, requests is likely used to fetch Feishu documents and related resources, so issues such as credential leakage, TLS/verification flaws, or redirect handling bugs could expose tokens or document data during network operations.
markdownify>=0.11.6 is also unpinned, so installations may resolve to different versions over time, including releases with undiscovered bugs or breaking behavior. Because this skill converts remote document content into Markdown, parser/converter dependencies are part of the trusted input-handling path and should be controlled precisely.
requests>=2.31.0
markdownify>=0.11.6
markdownify has known advisories, and without version pinning the installed version may still be vulnerable. Given this skill processes potentially large or untrusted document content and converts it to Markdown, parser-related flaws could enable denial of service or malformed output generation if a vulnerable release is resolved.
User-facing strings such as argument descriptions, status messages, and errors are consistently in Chinese, and the script does not provide any opt-in, locale selection, or justification for this language constraint. This can violate a language/locale policy when skills are expected to be usable without forcing a specific language.
The description promises preservation of formatting, images, and links, but the implementation relies on a generic HTML-to-Markdown conversion and only performs explicit post-processing for image URLs. There is no code verifying or enforcing preservation of links or broader formatting fidelity, so the implementation is weaker than the manifest suggests.
No suspicious patterns detected.