T01 · Skill Instruction Hijacking
- Location
SKILL.md:220- Finding
Remote Backend Controls the Agent's Primary User-Facing Response
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This recycle-estimate skill does what it claims, but it gives a remote service and caller-controlled endpoint too much influence over user data and final answers.
Review before installing. Use this only if you are comfortable sending valuation text and product photos to the Zhuanzhuan service, avoid passing arbitrary local files as images, and do not use --base-url except with a trusted approved endpoint. Treat backend-generated reply text as untrusted content if you maintain or wrap this skill.
SKILL.md:220Remote Backend Controls the Agent's Primary User-Facing Response
scripts/invoke_zhuanzhuan_recycle_skill.py:361Arbitrary Destination Override Can Exfiltrate User Data and Session Identifiers
The English long description says the skill should be 'triggered aggressively' for broad, everyday resale-value phrasing. This materially raises the risk of unintended invocation across normal shopping, appraisal, or casual 'what is this worth' conversations, which can lead to incorrect routing, unnecessary data handling, and degraded trust in the agent.
The README presents a Chinese-first structure with a dedicated “中文版” section but does not state that language is user-selectable or that Chinese is required for a region-specific reason. Under the stated policy, forcing a specific language or locale without opt-in can be a natural-language policy issue.
The README explicitly states the skill should match broad phrases such as '回收', '估价', '值多少钱', and similar resale-related wording. Broad trigger guidance can cause the orchestrator to invoke this skill in ambiguous conversations, increasing the chance of misrouting user requests and exposing user-provided images or product details to an unintended skill path.
The skill advertises executable capabilities through shell, file, environment, and network use, but does not declare any explicit tool scope or permission boundaries. In practice, this creates an over-privileged integration where the runtime may permit broader access than reviewers or policy expect, increasing the blast radius of prompt injection, SSRF, local file exposure, or unsafe state handling.
The description and the rest of the document are written as if the skill operates only in Chinese, but there is no opt-in or user-choice mechanism for language or locale. Under the policy, forcing a specific language without user choice is a natural-language policy concern unless clearly documented as a justified regional constraint.
The trigger list includes very broad resale-related phrases like '值多少钱', '卖掉', and '闲置', which can appear in many ordinary conversations outside the intended recycle-estimation flow. This can cause unintended activation, sending unrelated user text or images to the recycle backend and creating privacy, consent, and misrouting risks.
The skill explicitly says it should trigger even when the product category is not clearly stated, based only on partial descriptors or images. That lowers the threshold for activation and increases the chance that unrelated content, sensitive photos, or vague messages are processed by the skill without sufficient user intent validation.
This code file contains user-facing natural-language strings such as the module docstring, argparse descriptions, warnings, and output text entirely in Chinese. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is clearly documented and justified, which is not present here.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
def _has_command(cmd):
"""检查系统命令是否可用。"""
try:
subprocess.run([cmd, "--version"], capture_output=True)
return True
except FileNotFoundError:
return False
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
def _compress_with_sips(image_path, tmp_path, max_dim, quality):
"""macOS sips 压缩。"""
subprocess.run(
[
"sips",
"-s", "format", "jpeg",
The script invokes ImageMagick's convert on attacker-controlled local files. Even without shell injection, ImageMagick has a long history of delegate/protocol and file parsing issues, so processing untrusted images can lead to SSRF, local file reads via coders/delegates, or code execution depending on policy and version.
def _compress_with_convert(image_path, tmp_path, max_dim, quality):
"""ImageMagick convert 压缩(Linux 常用)。"""
subprocess.run(
[
"convert",
image_path,
The --base-url argument allows a caller to redirect outbound requests to any host, turning this skill into a generic HTTP client. In an agent context, that can be abused for SSRF-like access to internal services, data exfiltration of user text/images/session tokens, or bypass of intended domain restrictions.