Tp2
- Category
- MCP Tool Poisoning
- Confidence
- 85% confidence
- Finding
Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.
- Content
Security audit
Security checks for vulnerabilities and agentic risk
This is a coherent SVG drawing/export skill, but it automatically installs unpinned packages and renders SVG content in a no-sandbox browser.
Install only if you are comfortable with a skill that can write image files, run local rendering scripts, launch a detected browser, and download Python packages into a local .venv on first use. Prefer using it on SVGs you authored or trust, and consider pinning/vendor-locking dependencies and avoiding no-sandbox browser rendering for untrusted SVG input.
Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.
声明描述的是一个完整的“SVG 生图/作图/导出动画”技能,核心能力包括生成复杂 SVG、导出 PNG、制作 GIF/APNG/WebP/MP4 动图等。而实际代码块只是一个渲染脚本:输入必须是现成的 .svg 文件,输出主要是 .png,附带可选 HTML 包装,不包含任何根据用户指令生成 SVG 内容的逻辑,也没有多帧处理、动画编码或视频导出实现。代码中的自动安装依赖、查找浏览器、创建虚拟环境等属于实现细节,不构成额外越权能力;真正的问题是声明的主要能力范围明显大于代码实际行为,因此存在实质性描述不符。
os.system() and os exec-family calls run shell commands with the process's full privileges, enabling arbitrary command execution.
return False
if os.path.abspath(sys.executable) != os.path.abspath(PYBIN):
log("[python] re-exec under isolated venv python")
os.execv(PYBIN, [PYBIN, os.path.abspath(__file__)] + sys.argv[1:])
return True
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
"--no-first-run", "--no-default-browser-check",
"--disable-extensions", "--disable-sync",
"--disable-background-networking", "--disable-component-update",
"--password-store=basic", "--use-mock-keychain",
"--force-device-scale-factor=1",
"--virtual-time-budget=3000",
"--window-size=%d,%d" % (int(round(out_w)), int(round(out_h))),
The primary skill description is written entirely in Chinese and presents the skill as generally applicable to multiple agent runtimes, but it does not state that Chinese is required or offer an alternative language option. This can violate language/locale policy when users have not opted into Chinese-language instructions.
The skill explicitly instructs the agent to use file reads, file writes, and shell commands, yet it declares no tool scope restrictions. That creates a larger execution surface than users or platform policy can easily reason about, increasing the chance of unintended command execution or filesystem access during image rendering workflows.
The trigger phrases are extremely broad and overlap with many ordinary requests to create any image, poster, chart, cover, or animation. In combination with shell and file capabilities, this broad routing can cause the skill to activate in far more conversations than necessary, unnecessarily exposing rendering scripts and filesystem operations to routine prompts.
The entire skill content is written in Chinese and does not indicate that users may choose another language or that the locale restriction is required for a region-specific purpose. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation.
The entire skill manual is written in Chinese and provides instructions, examples, and labels exclusively in Chinese, with no indication that the language is optional or that the skill is limited to a China-specific or Chinese-language context. This can violate language/locale policy when users are not given an explicit opt-in or alternative locale.
The guidance explicitly requires Chinese font fallbacks, which imposes a Chinese-language locale assumption rather than offering it as an option. This is a natural-language policy concern because the file prescribes a specific language environment without indicating user choice or a justified region-specific scope.
The section declares Chinese-market conventions for stock colors and default currency symbol as universal defaults. Because the file does not clearly limit itself to China-specific output or instruct the user to choose locale-specific conventions, it violates the language/locale policy criteria.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
pass
# not importable here -> ensure venv + Pillow, then re-exec under venv python
if not os.path.exists(PYBIN):
subprocess.run([BASE_PY, "-m", "venv", VENV], check=True)
chk = subprocess.run([PYBIN, "-c", "import PIL"], capture_output=True)
if chk.returncode != 0:
log("[python] installing Pillow into isolated venv ...")
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
pass
# not importable here -> ensure venv + Pillow, then re-exec under venv python
if not os.path.exists(PYBIN):
subprocess.run([BASE_PY, "-m", "venv", VENV], check=True)
chk = subprocess.run([PYBIN, "-c", "import PIL"], capture_output=True)
if chk.returncode != 0:
log("[python] installing Pillow into isolated venv ...")
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
# not importable here -> ensure venv + Pillow, then re-exec under venv python
if not os.path.exists(PYBIN):
subprocess.run([BASE_PY, "-m", "venv", VENV], check=True)
chk = subprocess.run([PYBIN, "-c", "import PIL"], capture_output=True)
if chk.returncode != 0:
log("[python] installing Pillow into isolated venv ...")
r = subprocess.run([PIPBIN, "install", "-q", "Pillow"], capture_output=True, text=True)
This code performs an on-demand pip install Pillow at runtime from the network with no version pinning, hash verification, or trust policy. In environments with a malicious package index, compromised TLS/proxy settings, or dependency confusion, this can result in execution of untrusted code during installation.
chk = subprocess.run([PYBIN, "-c", "import PIL"], capture_output=True)
if chk.returncode != 0:
log("[python] installing Pillow into isolated venv ...")
r = subprocess.run([PIPBIN, "install", "-q", "Pillow"], capture_output=True, text=True)
if r.returncode != 0:
log("[python] Pillow install failed: %s" % (r.stderr or "")[-300:])
return False
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
cmd += ["--width", str(width)]
else:
cmd += ["--scale", str(scale)]
r = subprocess.run(cmd, capture_output=True, text=True)
if not (os.path.exists(png_path) and os.path.getsize(png_path) > 0):
log("[render] frame failed: %s\n%s" % (svg_path, (r.stderr or "")[-300:]))
return False
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
cmd += ["--width", str(width)]
else:
cmd += ["--scale", str(scale)]
r = subprocess.run(cmd, capture_output=True, text=True)
if not (os.path.exists(png_path) and os.path.getsize(png_path) > 0):
log("[render] frame failed: %s\n%s" % (svg_path, (r.stderr or "")[-300:]))
return False
Launching external browser and Python subprocesses is materially broader than passive file conversion, and here it is used to process untrusted SVG input. In this skill context, that matters because SVG is an active format and browser rendering can reach network, filesystem, and vulnerable browser code paths, turning a drawing utility into an execution surface.
The script opens untrusted SVG content in a headless browser, effectively treating user-supplied SVG as active web content. Because SVG can embed scripts, external resource loads, and browser-parsed payloads, this can enable SSRF, local file access attempts, or browser-engine exploitation, especially since the code also disables sandboxing with --no-sandbox.
# Chrome --headless=new with a fresh profile often writes the PNG
# then lingers without exiting. So: watch for the file instead of
# waiting for process exit, then kill the process ourselves.
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
ok = False
deadline = time.time() + 45
Auto-creating a venv and installing packages at runtime gives the skill network-enabled code acquisition and execution capabilities that exceed simple image rendering. In the context of an agent skill processing user files, that materially raises the risk of supply-chain compromise, unexpected code execution, and policy bypass.
The script performs runtime package installation with pip inside an auto-created virtual environment. In a rendering tool, this expands capability from file conversion to code retrieval and execution from package indexes, which creates a supply-chain and arbitrary code execution risk if package sources are tampered with or an attacker can influence the environment.
def pip_install(pkg):
py = ensure_venv()
log("[python] installing %s into isolated venv ..." % pkg)
r = subprocess.run([PIPBIN, "install", "-q", pkg], capture_output=True, text=True)
if r.returncode != 0:
log("[python] pip install %s failed: %s" % (pkg, (r.stderr or "")[-300:]))
return False
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
def render_cairosvg(svg_path, out_png, out_w, out_h, bg):
py = ensure_venv()
# check import in venv
chk = subprocess.run([py, "-c", "import cairosvg"], capture_output=True)
if chk.returncode != 0:
if not pip_install("cairosvg"):
return False
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
"cairosvg.svg2png(url=%r, write_to=%r, output_width=%d, output_height=%d, background_color=%s)"
% (svg_path, out_png, int(round(out_w)), int(round(out_h)), bg_arg)
)
r = subprocess.run([py, "-c", code], capture_output=True, text=True)
if os.path.exists(out_png) and os.path.getsize(out_png) > 0:
return True
log("[cairosvg] failed: %s" % (r.stderr or "")[-400:])
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
"cairosvg.svg2png(url=%r, write_to=%r, output_width=%d, output_height=%d, background_color=%s)"
% (svg_path, out_png, int(round(out_w)), int(round(out_h)), bg_arg)
)
r = subprocess.run([py, "-c", code], capture_output=True, text=True)
if os.path.exists(out_png) and os.path.getsize(out_png) > 0:
return True
log("[cairosvg] failed: %s" % (r.stderr or "")[-400:])
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
def render_resvg(svg_path, out_png, out_w, out_h, bg):
py = ensure_venv()
chk = subprocess.run([py, "-c", "import resvg_py"], capture_output=True)
if chk.returncode != 0:
if not pip_install("resvg-py"):
return False