Back to skill

Security audit

Virse Design

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches a Virse design-platform integration, but it handles credentials and includes a silent update/self-update path with too much trust and too little containment.

Install only if you trust the Virse service and this skill's GitHub update source. Before use, avoid setting VIRSE_BASE_URL to any untrusted host, understand that the skill can read and change Virse workspaces/canvases using your token, and review any proposed update before approving it.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/virse_call.py:25
Finding
Bearer Token Disclosure Through an Unrestricted Configurable API Endpoint## Vulnerability Details **File Location**: `scripts/virse_call.py:25-38, 116-124` **Vulnerability Type**: Credential disclosure through an untrusted network destination **Risk Level**: High ### Vulnerable Code ```python def _read_token(): """Read token: VIRSE_API_KEY env > ~/.virse/token file.""" token = os.environ.get("VIRSE_API_KEY", "").strip() if token: return token try: with open(TOKEN_PATH, "r") as f: return f.read().strip() except FileNotFoundError: return "" def _base_url(): return os.environ.get("VIRSE_BASE_URL", DEFAULT_BASE_URL).rstrip("/") ``` ```python def call_tool(name, args_json): base = _base_url() token = _read_token() endpoint = f"{base}/mcp" headers = {"Content-Type": "application/json", "Accept": "application/json, text/event-stream;q=0.9"} if token: headers["Authorization"] = f"Bearer {token}" ``` The same credential-forwarding behavior appears in `batch_call` at lines 169-177 and `list_tools` at lines 233-241. ### Technical Analysis The script reads a sensitive Virse bearer token from either `VIRSE_API_KEY` or `~/.virse/token`. Independently, it accepts the API destination from the unrestricted `VIRSE_BASE_URL` environment variable. It then attaches the token as an `Authorization` header to requests sent to that destination. The destination is not validated against an approved hostname, HTTPS is not enforced, and no restriction prevents an attacker-controlled origin from being selected. Consequently, any process, wrapper, CI configuration, or execution environment capable of influencing `VIRSE_BASE_URL` can redirect authenticated requests and capture the bearer token. Network transmission of a token to the default Virse endpoint is necessary for the Skill's declared cloud functionality. Allowing that credential to be forwarded to an arbitrary endpoint is not necessary and exceeds minimum privilege. No hardcoded malicious endpoint was identi ...[truncated 1487 chars]
Remediation
## Remediation Suggestions 1. **Restrict authenticated destinations** - Parse the configured URL with `urllib.parse.urlsplit`. - Require the `https` scheme. - Permit bearer-token transmission only to an explicit hostname allowlist, such as `dev.virse.ai`. - Reject embedded credentials, fragments, unexpected ports, malformed hosts, and ambiguous URLs. 2. **Separate production and development credentials** - If custom endpoints are required, require a separate development credential. - Never forward a production Virse token to a custom endpoint. - Require an explicit, clearly named opt-in for custom endpoints. 3. **Harden redirect handling** - Disable redirects for authenticated API requests or validate every redirect target. - Strip the `Authorization` header whenever the destination origin changes. - Reject HTTPS-to-HTTP redirects. 4. **Fail closed** - Abort before reading or attaching the token when endpoint validation fails. - Emit a clear error without printing the credential. - Apply the same centralized validation to `call_tool`, `batch_call`, `list_tools`, and OAuth endpoints. 5. **Update documentation** - Clearly warn that `VIRSE_BASE_URL` must not designate an untrusted service. - Prefer removing the override from ordinary user-facing authentication instructions unless it is operationally required. 6. **Add security tests** - Verify that HTTP endpoints are rejected. - Verify that non-allowlisted hosts do not receive authorization headers. - Verify that cross-origin redirects cannot receive credentials. - Verify that the default approved endpoint continues to work.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (30)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill is presented as a Virse design-platform integration, but it also contains update-check and self-update behavior that reaches out to external resources and can modify the local skill repository. That hidden extra capability expands the trust boundary and can surprise users or orchestrators that only expected design operations, increasing supply-chain and unintended-code-change risk.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The skill is presented as a Virse design-platform integration, but it also contains update-check and self-update behavior that reaches out to external resources and can modify the local skill repository. That hidden extra capability expands the trust boundary and can surprise users or orchestrators that only expected design operations, increasing supply-chain and unintended-code-change risk.

Vague Triggers

High
Confidence
97% confidence
Finding
The activation language is very broad ('any visual design task' even without naming Virse), which can cause the skill to be invoked for generic requests outside the user's intent. Over-broad routing is dangerous because it can expose external-tool actions, authentication flows, and remote operations in contexts where a simpler or safer capability should have been used.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
## Logout

```bash
rm ~/.virse/token
```

## Device Flow — Raw HTTP (for CI / scripts)
Confidence
85% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Lp1

High
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The script performs outbound network access to GitHub and git remotes, but the finding indicates this capability is not declared in permissions. Undeclared network behavior is dangerous because it bypasses least-privilege expectations, can surprise operators, and may allow unreviewed external communication during skill execution.

Lp1

High
Category
MCP Least Privilege
Confidence
75% confidence
Finding
The skill uses 'env' capability that is not listed in its permissions. This may indicate deceptive intent or missing permission declarations.

Lp1

High
Category
MCP Least Privilege
Confidence
75% confidence
Finding
The skill uses 'file_write' capability that is not listed in its permissions. This may indicate deceptive intent or missing permission declarations.

Natural-Language Policy Violations

Medium
Confidence
87% confidence
Finding
The playbook routing table includes Chinese trigger phrases alongside English ones, but the skill does not state that multilingual routing is optional or user-selected. This can create an implicit language/locale behavior without explicit opt-in or policy justification.

Description-Behavior Mismatch

Medium
Confidence
92% confidence
Finding
Local repository maintenance and file modification are unrelated to normal Virse design tasks and broaden the skill's ability to alter its own environment. This increases risk because a skill expected to manipulate remote design assets can also modify local files, making abuse or accidental corruption more plausible.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The skill includes a self-update path using git pull and in-place manifest editing, which can change code and metadata after deployment. Even with user consent, embedding this in an operational skill creates a supply-chain risk: a compromised repository, branch, or remote origin could cause the assistant to fetch and run altered code outside the user's original review.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
This markdown file instructs users to save an API key to `~/.virse/token` or export it as `VIRSE_API_KEY`, both of which affect credential storage and privacy. The section does not warn that the token will be stored locally or exposed to shell history/process environment depending on how the command is used.

External Transmission

Medium
Category
Data Exfiltration
Content
### Step 1 — Start device flow

```bash
curl -s -X POST https://dev.virse.ai/device/code \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'client_id=virse-skill'
```
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Vague Triggers

Medium
Confidence
91% confidence
Finding
The phrase "applicable to any multi-stage image generation pipeline" broadens the procedure beyond the clearly described product-listing use case, which can cause the agent to over-apply specialized workflow instructions in unrelated contexts. In a skill that is already activated for broad visual design tasks, this increases the chance of unintended execution, misuse of reference-chain cloning on the wrong canvas, or inappropriate manipulation of assets/workspaces.

Natural-Language Policy Violations

Medium
Confidence
98% confidence
Finding
The instruction "English only" hard-codes an output language without checking the user's language preference or the source material's language. This can override user intent, degrade accessibility/localization, and cause incorrect or non-compliant outputs for multilingual product workflows.

Vague Triggers

Medium
Confidence
90% confidence
Finding
The trigger keyword "curate" is generic and commonly used in normal conversation, so this playbook may activate in contexts not specifically about asset-folder organization. In an agent environment, overly broad activation can cause the wrong skill to run, leading to unintended access to canvas and asset metadata and actions such as folder creation or asset linking without clear user intent.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The trigger phrases are overly broad and include common user language such as 'create a set of' and 'lay them out', which can cause the skill to activate in conversations that are not specifically about the Virse platform. In an agent setting, this increases the chance of unintended tool use, unexpected workspace or canvas actions, and confusing cross-domain behavior when the user meant a generic design request rather than invoking this skill.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The trigger phrases are broad, generic terms like "clean up" and "organize," which can easily match ordinary user requests that are not specifically about canvas maintenance. In an agent-routing context, this can cause unintended invocation of the skill and lead to access to canvas state or destructive follow-on actions being proposed in the wrong context.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
- Overlapping elements (similar position ranges)
   - Empty/single-member groups
   - Outlier elements far from main content
3. **Report & ask** — Present audit findings and suggested actions to the user. **Get explicit confirmation before making any changes.** Never delete without confirmation.
4. **Apply** — Based on user choices:
   - Re-layout: `update_element` to reposition into clean grid
   - Group clusters: `create_group(element_ids=[...])`
Confidence
75% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The trigger keywords include very broad terms like "consolidate" and "gather images matching X," which can cause the skill to activate in contexts where the user did not explicitly intend a cross-workspace operation. In this skill, unintended invocation is more dangerous because the playbook performs multi-workspace enumeration and asset collection, potentially exposing or reorganizing data across broad scopes once triggered.

Vague Triggers

Medium
Confidence
97% confidence
Finding
The trigger list includes broad, everyday phrases like 'iterate', 'keep tweaking', and 'improve step by step' that can match many normal conversations unrelated to this specific Virse workflow. This can cause unintended skill activation, leading the agent to invoke design/image-generation actions in contexts where the user did not clearly request this capability.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger phrases are very broad and map to common design-related language such as 'find references' or 'organize', which can cause the skill to activate when a user did not explicitly intend to use Virse. In an agentic environment, overbroad invocation increases the chance of unintended external actions like workspace creation, image search, and canvas modification without sufficiently clear user intent.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger list includes the generic term "compare" without constraining it to Virse, images, canvases, models, or design workflows. In an agent environment, this can cause the skill to activate for unrelated user requests, leading to unintended tool use, context hijacking, or execution of design actions when the user did not intend to invoke this skill.

External Transmission

Medium
Category
Data Exfiltration
Content
def get_remote_hash_github() -> str | None:
    """Get latest commit hash from GitHub API (no git required)."""
    url = f"https://api.github.com/repos/{GITHUB_REPO}/commits/{GITHUB_BRANCH}"
    req = urllib.request.Request(url, headers={
        "Accept": "application/vnd.github.v3+json",
        "User-Agent": "virse-skill-updater",
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
"""Get latest remote hash via git (fetch then rev-parse, fallback to ls-remote)."""
    # Try fetch + rev-parse
    try:
        fetch = subprocess.run(
            ["git", "-C", skill_dir, "fetch", "origin", GITHUB_BRANCH, "--quiet"],
            capture_output=True, text=True, timeout=30,
        )
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
capture_output=True, text=True, timeout=30,
        )
        if fetch.returncode == 0:
            rev = subprocess.run(
                ["git", "-C", skill_dir, "rev-parse", f"origin/{GITHUB_BRANCH}"],
                capture_output=True, text=True, timeout=5,
            )
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Static analysis

No suspicious patterns detected.