Back to skill

Security audit

Canvas Workspace

Security checks across malware telemetry and agentic risk

Overview

This canvas image skill is mostly aligned with its purpose, but it needs review because it launches unpinned remote code, stores API keys persistently, fetches arbitrary URLs, and documents a destructive reset endpoint without guardrails.

Install only if you trust the npm package and the Qwen/Gemini endpoints. Prefer setting API keys yourself in a temporary or scoped secret store, avoid giving it private/internal image URLs, and require explicit confirmation before launching setup, fetching URLs, or calling any reset endpoint.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (8)

Tainted flow: 'req' from os.environ.get (line 129, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
req = urllib.request.Request(url, data=data, headers=headers, method="POST")

    try:
        with urllib.request.urlopen(req, timeout=300) as resp:
            result = json.loads(resp.read().decode("utf-8"))
    except urllib.error.HTTPError as e:
        error_body = e.read().decode("utf-8", errors="replace")
Confidence
90% confidence
Finding
with urllib.request.urlopen(req, timeout=300) as resp:

Tainted flow: 'req' from os.environ.get (line 129, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
method="POST",
    )
    try:
        with urllib.request.urlopen(req, timeout=30) as resp:
            result = json.loads(resp.read().decode("utf-8"))
            return result.get("url", "")
    except Exception:
Confidence
82% confidence
Finding
with urllib.request.urlopen(req, timeout=30) as resp:

Tainted flow: 'req' from os.environ.get (line 74, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
def _download_and_upload(image_url: str) -> str:
    """下载远程图片并上传到本地服务器,返回本地 URL"""
    req = urllib.request.Request(image_url, headers={"User-Agent": "Mozilla/5.0"})
    with urllib.request.urlopen(req, timeout=60) as resp:
        image_data = resp.read()
        content_type = resp.headers.get("Content-Type", "image/png")
Confidence
96% confidence
Finding
with urllib.request.urlopen(req, timeout=60) as resp:

Context-Inappropriate Capability

Medium
Confidence
98% confidence
Finding
The workflow instructs the agent to collect user API keys and persist them as permanent user/system environment variables, which exceeds the immediate task of image generation and creates durable secret exposure. Persisting secrets in shell profiles or user environment stores increases the blast radius across future sessions, other tools, and unrelated processes, and may overwrite existing secure setups.

Intent-Code Divergence

Medium
Confidence
93% confidence
Finding
The privacy section gives a reassuring statement that environment-variable values will not leave the machine, while the workflow explicitly asks the agent to solicit and install API keys into the host environment. Even if the keys are not transmitted externally by the skill itself, this framing is misleading because it downplays the security sensitivity of collecting and persistently storing secrets on the endpoint.

Description-Behavior Mismatch

Medium
Confidence
87% confidence
Finding
The documentation exposes a destructive `reset` capability that clears all canvas data, but the skill metadata/description does not disclose this high-risk action. In an agent setting, undocumented destructive capabilities increase the chance that the agent invokes them unexpectedly or without informed user consent, causing data loss.

Vague Triggers

Medium
Confidence
87% confidence
Finding
The activation keywords are broad and include common terms such as drawing, image generation, editing, and canvas-related words, making accidental auto-activation plausible in unrelated conversations. In an agent setting, overbroad triggering is dangerous because it can cause unsolicited startup of local services, network use, file handling, or secret-collection workflows without strong user intent.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
A destructive wipe endpoint is documented with no warning, confirmation requirement, or safe-use note. In a tool-using agent environment, this omission is dangerous because the model may treat it as a routine operation and erase user workspace contents without clear authorization.

VirusTotal

66/66 vendors flagged this skill as clean.

View on VirusTotal