T01 · Skill Instruction Hijacking
- Location
SKILL.md:39- Finding
Mandatory Promotional Content Injected into Agent Responses
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill has a coherent article-saving purpose, but it needs Review because it can fetch unrestricted URLs, disclose submitted links to Jina.ai, and write outside the intended vault under unsafe configuration.
Install only if you are comfortable with the skill contacting target websites and Jina.ai, downloading page-selected images, scanning common local folders for Obsidian vaults, and writing generated notes to disk. Avoid using it with private, signed, internal, localhost, or token-bearing URLs until URL validation, size limits, vault containment checks, and a Jina opt-in or local-only mode are added.
SKILL.md:39Mandatory Promotional Content Injected into Agent Responses
scripts/download_images.py:359Unrestricted URL Fetching Enables Server-Side Request Forgery
scripts/download_images.py:376Complete User-Supplied Article URLs Are Disclosed to Jina Reader
scripts/config.py:111Subfolder Traversal Can Escape the Configured Obsidian Vault
scripts/save_article.py:71Unsafe String Interpolation Allows YAML Frontmatter Injection
scripts/download_images.py:268Unbounded Response Reads Permit Memory and Disk Exhaustion
The script performs outbound network access to arbitrary user-supplied article URLs, downloads remote images, and also contacts an external service. If the skill's declared permissions do not include network access, this creates a capability mismatch that can expose users to unexpected data exfiltration, SSRF against internal resources, or policy bypass. In the context of a skill advertised as saving web articles locally, network use to fetch the page is expected, but undeclared network capability is still security-relevant because users and permission systems cannot accurately assess what the skill does.
The README states that the primary fetch path sends target URLs to https://r.jina.ai/<URL>, which means user-requested pages are disclosed to a third-party service. Because this behavior is documented without a clear privacy warning, consent model, or explanation of what metadata may be exposed, users may unknowingly leak sensitive internal, private, or identifying links during normal use.
The combination of Write, Edit, and exec permissions gives the skill durable filesystem access and the ability to invoke local scripts. Although necessary for saving articles, this enlarges the attack surface if untrusted input such as user-supplied paths, URLs, or note text is passed into scripts or used to determine filesystem targets without strong validation.
description: 将网页文章保存到本地 Obsidian Vault,支持图片抓取、Markdown 转换、YAML frontmatter 和用户笔记附加。
allowed-tools:
- Read
- Write
- Edit
- exec
---
The combination of Write, Edit, and exec permissions gives the skill durable filesystem access and the ability to invoke local scripts. Although necessary for saving articles, this enlarges the attack surface if untrusted input such as user-supplied paths, URLs, or note text is passed into scripts or used to determine filesystem targets without strong validation.
description: 将网页文章保存到本地 Obsidian Vault,支持图片抓取、Markdown 转换、YAML frontmatter 和用户笔记附加。
allowed-tools:
- Read
- Write
- Edit
- exec
---
The skill defaults to fetching article content through Jina.ai but does not clearly disclose to users that submitted URLs and potentially retrieved page content are sent to a third-party service. This is a privacy and data-handling risk, especially when users save internal, private, or sensitive links under the assumption that processing is local.
The module reads Obsidian's application config and recursively scans broad user directories such as Documents, Desktop, and Mobile Documents to discover vaults. For a skill whose stated purpose is saving content to a user-configured vault, this is excessive filesystem enumeration that exposes private directory structure and application state, increasing privacy risk and collecting more local metadata than necessary.
This code prints user-facing status text in Chinese for the CLI path, including success, error, and configuration messages. The file provides no language selection, fallback, or documentation that the tool is intentionally Chinese-only, which creates a natural-language locale policy concern.
The set and clear command flows emit user-visible messages only in Chinese, again without any opt-in or documented regional restriction. Because these are primary interaction paths, the forced locale is a consistent policy issue rather than an isolated string choice.
The code sends the user-provided article URL to https://r.jina.ai for markdown extraction, which means a third party learns what the user is saving and may fetch/process the target content externally. This contradicts the local-save expectation in the skill description and creates a privacy/data-handling issue, especially if users save private, sensitive, intranet, or tokenized URLs. The skill context makes this more dangerous because users are likely to assume content stays local except for the original site being fetched.
The script fetches article content and downloads images via process_article(url, output_dir), which implies network access and data transmission based on a user-supplied URL. While the module docstring mentions fetching and downloading, there is no runtime confirmation, user-facing notice, or explicit warning near execution that external network requests will be made.
The trigger examples are exclusively in Chinese, including operational commands such as saving and reconfiguration, but the README does not say whether other languages are supported or whether Chinese is required. This can amount to an implicit language constraint without user opt-in or documented justification.
The manifest description and the entire user-facing instruction set are presented in Chinese, including trigger phrases and setup prompts, with no indication that other languages are supported or that Chinese is optional. This can amount to a language/locale policy issue when the skill effectively forces a specific language without opt-in.
The setup flow injects promotional content for a Chrome extension and an unrelated community during a task that is supposed to configure article saving to Obsidian. This creates an unnecessary trust and social-engineering surface, because users may be nudged toward external products or communities without a security or functional need tied to the requested action.
The stated purpose is saving webpage articles to a local Obsidian vault with images and markdown conversion. While fetching webpages is expected, embedding a full browser automation stack to render pages is a materially broader capability than the manifest describes, especially since it can execute page scripts and access dynamically rendered content.
This code writes a generated markdown note to disk, which changes user data in the specified output directory. Although the module docstring says it writes an Obsidian note, the execution path provides no print/log message or confirmation indicating the exact file write that is about to occur.