Back to skill

Security audit

Pve Builder

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real Proxmox VM helper, but it handles passwords and generated shell commands unsafely enough that users should review it carefully before installing.

Install only if you are prepared to inspect every generated command before running it on a Proxmox host. Do not reuse passwords with this skill, avoid password SSH where possible, and treat pve-env.md, VM names, key paths, URLs, disk names, and package names as sensitive inputs that could alter generated shell commands. Prefer a revised version that validates inputs, shell-quotes generated commands, avoids printing passwords, and uses safer filesystem/process APIs for local key generation.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
agent.js:186
Finding

Local Command Injection Through Unsanitized SSH Key Paths and VM Names

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
agent.js:442
Finding

Command and Configuration Injection in Generated Root-Level Proxmox Commands

Content
View full analysis
${userDataPath}`); lines.push(userData.trim()); lines.push(`EOF`); lines.push(''); lines.push(`# Create VM`); lines.push(`qm create ${vmid} \\`); lines.push(` --name ${vmName} \\`); lines.push(` --memory ${ramMb} \\`); lines.push(` --cores ${cpu} \\`); lines.push(` --sockets ${sockets} \\`); lines.push(` --cpu ${cpuType} \\`); lines.push(` --machine ${machineType} \\`); lines.push(` --bios ${biosType} \\`); lines.push(` --ostype ${osType} \\`); lines.push(` --scsihw ${scsiCtrl} \\`); lines.push(` --onboot ${onboot}`); lines.push(''); lines.push(`# Import cloud image as OS disk`); lines.push(`qm importdisk ${vmid} ${imagePath} ${storageForCmd} --format raw`); lines.push(`qm set ${vmid} --scsi0 ${storageForCmd}:vm-${vmid}-disk-0,discard=on,ssd=1`); lines.push(`qm resize ${vmid} --scsi0 ${osDisk}`); lines.push(''); lines.push(`# Network`); lines.push(`qm set ${vmid} --net0 ${netIface},bridge=${selBridge}${vlan ? `,tag=${vlan}` : ''}`); lines.push(''); lines.push(`# Cloud-init`); lines.push(`qm set ${vmid} --ide0 ${storageForCmd}:cloudinit`); if (useDhcp) { lines.push(`qm set ${vmid} --ipconfig0 ip=dhcp`); } else { const ipStr = `ip=${staticIp.address}`; const gwStr = staticIp.gw ? `,gw=${staticIp.gw}` : ''; lines.push(`qm set ${vmid} --ipconfig0 ${ipStr}${gwStr}`); const dnsList = staticIp.dns.split(',').filter(Boolean); lines.push(`qm set ${vmid} --nameserver ${dnsList.join(' ')}`); } lines.push(`qm set ${vmid} --ciuser ${sshUser}`); lines.push(`qm set ${vmid} --sshkeys "${pubKeyContent}"`); ...[truncated 3910 chars]
Remediation
View remediation
`. - Keep cleanup in a separate post-boot section. - Do not remove the cloud-init file before successful first boot. 9. Add automated tests containing spaces, quotes, semicolons, newlines, command substitutions, leading dashes, and malformed network values to verify that generated output cannot change command structure. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
agent.js:158
Finding

Unrestricted User-Controlled URL Fetching Enables SSRF

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (28)

Ssd 3

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The instruction to always display generated or user-provided passwords in the final output causes direct credential disclosure into chat logs, terminal scrollback, screenshots, and any downstream observability systems. This is especially dangerous because it normalizes revealing secrets even when the password was user-supplied and may be reused elsewhere.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The security section explicitly mandates embedding the VM password in command output, which guarantees sensitive credential exposure in persistent logs and transcripts. Because the skill also sets ssh_pwauth: true by default, the disclosed secret may immediately enable network login if the VM is reachable.

Content

No source excerpt is available for this finding.

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.

Content

No source excerpt is available for this finding.

Lp1

High
Category
MCP Least Privilege
Confidence
75% confidence
Finding

The skill uses 'network' capability that is not listed in its permissions. This may indicate deceptive intent or missing permission declarations.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

The generated cleanup command embeds the untrusted vmName directly into a shell rm command without quoting or sanitization. If a user enters shell metacharacters or path traversal sequences in the VM name, the generated command could delete unintended files when executed on the Proxmox host.

Content

Scanner excerpt · agent.js (reported line 539)May include surrounding context.

js
lines.push(`# Cleanup: list cloud-init YAML files`);
  lines.push(`echo "=== Current cloud-init YAML files ===" && ls -la /var/lib/vz/template/cloud-init/*.yaml 2>/dev/null || echo "(none)"`);
  lines.push(`# Review the list above. Delete confirmed files one by one:`);
  lines.push(`rm -v /var/lib/vz/template/cloud-init/${vmName}-user-data.yaml`);
  lines.push(`# Or remove all stale files (older than 30 days):`);
  lines.push(`# ls /var/lib/vz/template/cloud-init/*.yaml`);
  lines.push(`# rm -v /var/lib/vz/template/cloud-init/<FILE.yaml>  # repeat for each file`);

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% 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).

Content

Scanner excerpt · agent.js (reported line 542)May include surrounding context.

js
lines.push(`rm -v /var/lib/vz/template/cloud-init/${vmName}-user-data.yaml`);
  lines.push(`# Or remove all stale files (older than 30 days):`);
  lines.push(`# ls /var/lib/vz/template/cloud-init/*.yaml`);
  lines.push(`# rm -v /var/lib/vz/template/cloud-init/<FILE.yaml>  # repeat for each file`);

  const output = lines.join('\n');

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill frames itself as a command-generation-only workflow and explicitly says it must not execute Proxmox commands, but later requires local execution of a generated shell script via exec. Even if the script is intended only for parameter validation, this expands the trust boundary and creates an unnecessary code-execution path from skill-controlled content on the analyst's machine.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · SKILL.md (reported line 105)May include surrounding context.

md
18. **VMID auto-detection** — Ask the user to run `pvesh get /cluster/nextid` on the Proxmox node and paste back the result. Use that VMID in all generated commands. Never hardcode a VMID — always get the next ID from the cluster. Add a `# Replace VMID=... if already taken` comment in the output.
19. Build cloud-init user-data YAML (packages, proxy, data disk formatting)
20. **Pre-flight validation** (see Command Pre-flight Validation below) — generate commands internally, validate, fix errors, then present
21. Generate and display the final verified commands in two sections: **Setup commands** (create VM through `qm start`) and **Post-boot cleanup** (delete the snippets YAML — only run after the VM is verified up).
22. Optional: save commands to file
22. Show SSH key path and chmod reminder

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The pre-flight section instructs the agent to write and run a local shell script, which is broader authority than needed for a skill whose main function is generating Proxmox commands as text. Any local execution pathway increases the chance of command injection, unintended environment access, or harmful side effects if parameters are mishandled.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill requires creating and executing a local pre-flight shell script but does not clearly warn the user that local commands will be run on their machine. This undermines informed consent and can surprise users with filesystem or process activity outside the stated scope of a command-generation helper.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

Validation results for node, storage, and bridge are cached on disk under the user's home directory without notice or access control hardening. While the cached data is not highly sensitive, it can disclose infrastructure details and persists longer than users may expect.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill generates SSH private keys and writes them to disk automatically, including a fallback that writes placeholder private key material, without explicit user consent or a security warning. Secret material stored in predictable locations can be exposed through weak filesystem permissions, backups, or accidental sharing.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 246)May include surrounding context.

md
await writeFile(priv, `-----BEGIN PRIVATE KEY-----\nPlaceholder for ${uniqueId}\n-----END PRIVATE KEY-----`);
    await writeFile(pub, `${keyType} AAAAC3NzaC1lZDI1NTE5AAAAI... placeholder - ${uniqueId}`);
  }
  await execCmd(`chmod 600 ${priv} ${pub}`);
  return { privateKey: priv, publicKey: pub };
}

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 247)May include surrounding context.

md
await writeFile(priv, `-----BEGIN PRIVATE KEY-----\nPlaceholder for ${uniqueId}\n-----END PRIVATE KEY-----`);
    await writeFile(pub, `${keyType} AAAAC3NzaC1lZDI1NTE5AAAAI... placeholder - ${uniqueId}`);
  }
  await execCmd(`chmod 600 ${priv} ${pub}`);
  return { privateKey: priv, publicKey: pub };
}

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · agent.js (reported line 192)May include surrounding context.

js
await writeFile(priv, `-----BEGIN PRIVATE KEY-----\nPlaceholder for ${uniqueId}\n-----END PRIVATE KEY-----`);
    await writeFile(pub, `${keyType} AAAAC3NzaC1lZDI1NTE5AAAAI... placeholder - ${uniqueId}`);
  }
  await execCmd(`chmod 600 ${priv} ${pub}`);
  return { privateKey: priv, publicKey: pub };
}

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · agent.js (reported line 557)May include surrounding context.

js
await writeFile(priv, `-----BEGIN PRIVATE KEY-----\nPlaceholder for ${uniqueId}\n-----END PRIVATE KEY-----`);
    await writeFile(pub, `${keyType} AAAAC3NzaC1lZDI1NTE5AAAAI... placeholder - ${uniqueId}`);
  }
  await execCmd(`chmod 600 ${priv} ${pub}`);
  return { privateKey: priv, publicKey: pub };
}

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · qm-reference.md (reported line 309)May include surrounding context.

md
await writeFile(priv, `-----BEGIN PRIVATE KEY-----\nPlaceholder for ${uniqueId}\n-----END PRIVATE KEY-----`);
    await writeFile(pub, `${keyType} AAAAC3NzaC1lZDI1NTE5AAAAI... placeholder - ${uniqueId}`);
  }
  await execCmd(`chmod 600 ${priv} ${pub}`);
  return { privateKey: priv, publicKey: pub };
}

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · qm-reference.md (reported line 335)May include surrounding context.

md
await writeFile(priv, `-----BEGIN PRIVATE KEY-----\nPlaceholder for ${uniqueId}\n-----END PRIVATE KEY-----`);
    await writeFile(pub, `${keyType} AAAAC3NzaC1lZDI1NTE5AAAAI... placeholder - ${uniqueId}`);
  }
  await execCmd(`chmod 600 ${priv} ${pub}`);
  return { privateKey: priv, publicKey: pub };
}

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The examples use mkfs.ext4 and append entries to /etc/fstab, which can erase existing data on the target disks and make persistent system changes. The surrounding markdown describes the behavior but does not clearly warn users about the destructive nature of formatting or the need to verify device mappings first.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This markdown file documents qm destroy <VMID>, which deletes a VM, but it does not explicitly warn that the action is destructive and may permanently remove VM data. Under the markdown-file criteria for missing user warnings, destructive operations that can affect user data should be accompanied by a warning.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · agent.js (reported line 425)May include surrounding context.

js
# Run commands on first boot
runcmd:
  - systemctl enable qemu-guest-agent
  - systemctl start qemu-guest-agent
  - echo "Cloud-init complete at $(date)" >> /var/log/cloud-init-complete.log

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · qm-reference.md (reported line 186)May include surrounding context.

md
# Run commands on first boot
runcmd:
  - systemctl enable qemu-guest-agent
  - systemctl start qemu-guest-agent
  - echo "Cloud-init complete at $(date)" >> /var/log/cloud-init-complete.log

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The runcmd template includes mkfs.ext4 /dev/sdb and mkfs.ext4 /dev/sdc, which are destructive operations executed automatically on first boot. The markdown provides mapping notes, but it lacks an explicit warning that a wrong device selection can permanently erase data and affect system integrity.

Content

No source excerpt is available for this finding.

Behavior Manipulation

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Subtle instructions detected that may alter agent decision-making or introduce hidden biases.

Content

Scanner excerpt · qm-reference.md (reported line 332)May include surrounding context.

md
## Best Practices

- Always use SSH keys instead of passwords
- Generate unique SSH key per VM
- Store keys in a configurable directory (default: ~/.ssh/pve-builder/)
- Set private key permissions to chmod 600

Lp4

Low
Category
MCP Least Privilege
Confidence
65% confidence
Finding

Declared permissions with no matching code capability may indicate removed functionality or pre-staging for future abuse.

Content

No source excerpt is available for this finding.