T09 · Insecure Skill Coding Practices
- Location
scripts/analyze.py:103- Finding
Unrestricted Image URL Fetching Enables Server-Side Request Forgery
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
Ghost Eye does what it says, but it can automatically send every inbound image to a third-party vision API and stores OCR results in plaintext by default.
Review this skill before installing. Use explicit tool-call mode instead of global auto-preprocess for sensitive work, set an approved vision endpoint, avoid --image-url unless network egress is constrained, and disable or regularly clear caching when images may contain personal, business, credential, or regulated data.
scripts/analyze.py:103Unrestricted Image URL Fetching Enables Server-Side Request Forgery
scripts/analyze.py:71OCR and Image Analysis Results Are Persisted in Plaintext by Default
The auto-preprocess mode explicitly says the skill fires automatically on inbound images and 'the user never knows it's there,' while sending those images to an external vision model. Hidden third-party processing of user images is a serious privacy and consent issue, especially because images may contain sensitive personal, financial, or confidential business information.
Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.
{"content": "【OCR文字提取】\n\n← Back to Ghost Eye\n\n# Skill settings\n\nIntegrations \nAutomation \nResearch \nDevelopment \nProductivity \nCommunication \nCreative \nKnowledge \nAgents \nOperations \nSecurity \nFinance \nLifestyle \n✓ Other\n\nUpdate skill files\n\n## Publish a new version\n\nUpload a replacement release for this skill. New releases get a fresh scan.\n\nNew Version\n\n## Short summary\n\nUpdate the short summary used in cards, search, and previews.\n\nages through any vision model. OCR + visual\n\nSave\n\n## Catalog metadata\n\nChoose browse categories and author topics for this skill.\n\nOther\n\n## TOPICS\n\nAdd a topic\n\n【画面内容总结】\n\n1. 核心主题: \n 图片展示的是一个名为 “Skill settings” 的技能设置页面,用户正在编辑或配置某个技能的基本信息、分类、摘要、版本发布和主题等元数据。\n\n2. 元素与布局: \n - 页面左上角有返回入口 “Back to Ghost Eye”。 \n - 主标题为 “Skill settings”。 \n - 页面主要分为左侧设置说明区和右侧操作/输入区。 \n - 中间偏上位置弹出了一个分类选择下拉菜单,包含 Integrations、Automation、Research、Development、Productivity、Communication、Creative、Knowledge、Agents、Operations、Security、Finance、Lifestyle、Other 等分类。 \n - 下拉菜单中 “Automation” 被红色边框高亮,表示当前鼠标悬停或正在选择该项。 \n - 下方当前选中的分类显示为 “Other”,并带有勾选标记。 \n - 页面右侧有 “Update skill files”、“New Version”、“Save” 等操作按钮。 \n - 页面底部有 “TOPICS” 主题输入框,占位文字为 “Add a topic”。\n\n3. 关键信息提炼: \n - 当前页面用于配置技能设置。 \n - 用户正在从分类下拉菜单中选择 “Automation”,但当前已选分类仍显示为 “Other”。 \n - 页面支持发布新版本、更新技能文件、编辑短摘要、设置目录分类和添加主题。 \n - “Automation” 是下拉菜单中被重点标记的选项,说明用户可能准备将技能分类从 “Other” 改为 “Automation”。", "cached_at": "2026-07-09T15:38:45.194194+00:00", "expires_at": "2026-07-16T15:38:45.194194+00:00", "model": "nex-agi/Nex-N2-Pro", "tokens_used": 4393}
The skill documentation describes capabilities to read local files, access environment variables, and send image content over the network, but it does not declare any explicit permission or allowed-tools scope. That gap weakens security review and policy enforcement because operators cannot clearly see or constrain what the skill is allowed to access before enabling it.
Documenting image-path input as having 'no size limit' suggests the skill may accept arbitrarily large local files for processing. Even with later compression, unbounded intake can enable denial-of-service through oversized or decompression-heavy images that consume memory, CPU, disk, or API quota.
⛔ Always prefer --image-path to avoid command-line Argument list too long errors with large base64 strings. Only fall back to --image-url or --image-base64 when no local path is available.
# Preferred: local file path (no size limit)
python3 {baseDir}/scripts/analyze.py --image-path "<absolute path>"
# Fallback: public URL
The example success output uses Chinese section headers, and the documentation explicitly says missing API key errors return a friendly Chinese message. This indicates a language choice is being imposed by default rather than offering the user's preferred language or documenting a justified locale restriction.
The skill is designed to transmit image data to an external API endpoint, which is a real data egress behavior. In context this is expected functionality, but it remains security-relevant because the transmitted images may contain sensitive content and the default remote endpoint is third-party infrastructure.
| Variable | Required | Default |
|----------|----------|---------|
| NEXN2_API_KEY | ✅ Yes | — |
| NEXN2_BASE_URL | No | https://api.siliconflow.cn/v1 |
| NEXN2_MODEL_NAME | No | nex-agi/Nex-N2-Pro |
| NEXN2_PROMPT_TEMPLATE | No | Built-in structured template |
| NEXN2_IMAGE_COMPRESS | No | true |
The line states that if the API key is missing, the skill returns a friendly Chinese error message. This is a natural-language policy issue because it fixes a specific language for user-facing output without opt-in or justification.
The setup example hardcodes a default third-party base URL, reinforcing that image content will be sent off-box unless reconfigured. Although this aligns with the skill's purpose, it still creates a genuine confidentiality and compliance risk if users are unaware or cannot constrain where their images go.
"enabled": true,
"apiKey": { "source": "env", "provider": "default", "id": "NEXN2_API_KEY" },
"env": {
"NEXN2_BASE_URL": "https://api.siliconflow.cn/v1",
"NEXN2_MODEL_NAME": "nex-agi/Nex-N2-Pro",
"NEXN2_IMAGE_COMPRESS": "true",
"NEXN2_CACHE_ENABLE": "true",
This JSON file is a manifest-like cache record containing the skill's descriptive content, but it does not define when the skill should activate or what phrases should invoke it. Without explicit trigger scope or exclusion conditions, the activation semantics are ambiguous and could lead to unintended invocation if this content is reused as metadata.
The natural-language content and headings in the stored skill description are exclusively Chinese, including the skill title and summary text. There is no indication that users can opt into this language or that the skill is intentionally restricted to a Chinese-language audience for a documented reason.
The documentation instructs users to enable automatic image preprocessing that sends image content to an external vision model, but it does not warn that screenshots, photos, or documents may contain sensitive personal, corporate, or regulated data. Because this is a global automatic flow, users may unknowingly transmit private content off-platform, increasing privacy and compliance risk.
The tool-call guidance tells the system to analyze user-submitted images and screenshots via an external service, but omits any notice that the image contents and OCR text will leave the local environment. This can cause inadvertent disclosure of sensitive information embedded in screenshots or documents, especially when the instruction is reused verbatim by integrators.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
Environment:
NEXN2_API_KEY required
NEXN2_BASE_URL default https://api.siliconflow.cn/v1
NEXN2_MODEL_NAME default nex-agi/Nex-N2-Pro
NEXN2_PROMPT_TEMPLATE optional custom prompt
NEXN2_IMAGE_COMPRESS default true
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
Environment:
NEXN2_API_KEY required
NEXN2_BASE_URL default https://api.siliconflow.cn/v1
NEXN2_MODEL_NAME default nex-agi/Nex-N2-Pro
NEXN2_PROMPT_TEMPLATE optional custom prompt
NEXN2_IMAGE_COMPRESS default true
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
Environment:
NEXN2_API_KEY required
NEXN2_BASE_URL default https://api.siliconflow.cn/v1
NEXN2_MODEL_NAME default nex-agi/Nex-N2-Pro
NEXN2_PROMPT_TEMPLATE optional custom prompt
NEXN2_IMAGE_COMPRESS default true
The cache stores extracted analysis content and metadata on local disk without any notice, encryption, access control hardening, or content sensitivity checks. OCR output can contain secrets, personal data, or regulated information, so persisting it silently increases the exposure window beyond the original API call.
The default prompt explicitly instructs the model to produce output in Chinese, and multiple user-facing error messages are also hard-coded in Chinese. This imposes a specific language/locale without any opt-in, language selection mechanism, or documented region-specific justification, which matches the language-policy violation criterion.
The script sends full image contents to a third-party API endpoint for analysis, but the code contains no consent, disclosure, or policy gate before transmission. Because images may contain sensitive personal, business, or credential information, silent exfiltration to an external service creates a real privacy and data-handling risk in this skill context.
The top-level docstring presents this file as a different tool/product name rather than the declared skill name. While the code still performs image analysis, the embedded documentation contradicts the stated skill identity and creates intent ambiguity about what component this actually is.