T09 · Insecure Skill Coding Practices
- Location
scripts/pve.sh:31- Finding
TLS Certificate Verification Is Disabled for Authenticated Proxmox Requests
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This Proxmox administration skill is not deceptive, but it needs Review because it can change infrastructure and has unsafe credential, TLS, and approval-control gaps.
Install only if you are comfortable reviewing and tightening it first. Use a least-privilege Proxmox token, enable TLS verification with a trusted certificate, avoid the Bash fallback credential file, pin dependencies, and require an explicit per-action confirmation before any power, snapshot, rollback, deletion, or backup command runs.
scripts/pve.sh:31TLS Certificate Verification Is Disabled for Authenticated Proxmox Requests
scripts/pve.sh:8Shell Credential File Is Executed as Arbitrary Code
README.md:101Proxmoxer Dependency Is Installed Without Version or Integrity Pinning
scripts/pve.sh:178Destructive Proxmox Operations Do Not Enforce the Documented Approval Requirement
The script interpolates user-controlled values such as node, vmtype, vmid, and especially snapname directly into REST API path segments without validation or URL encoding. This can allow path manipulation or malformed requests against the Proxmox API, potentially causing deletion of unintended snapshots or other destructive actions if crafted values alter endpoint resolution.
fi
vmtype=$(get_type_for_vmid "$vmid")
echo "Deleting snapshot '$snapname' from $vmtype $vmid..."
api DELETE "/nodes/$node/$vmtype/$vmid/snapshot/$snapname" | jq
;;
backups)
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.
- **Power Control**: Start, stop, reboot, shutdown VMs and containers
- **Snapshots**: Create, list, delete, rollback (with optional RAM state)
- **Backups**: List and create backups
- **Storage**: View storage pools and content
- **Tasks**: Track async operations and logs
- **Cluster Overview**: Nodes, resources, health stats
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.
- Snapshots: `snapshot`, `delete_snapshot`, `rollback`
- Backups: `backup`
Read-only (no approval):
- `nodes`, `vms`, `status`, `list_snapshots`
- `backups` (list), `storage`, `tasks`, `health`
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.
- Snapshots: `snapshot`, `delete_snapshot`, `rollback`
- Backups: `backup`
Read-only (no approval):
- `nodes`, `vms`, `status`, `list_snapshots`
- `backups` (list), `storage`, `tasks`, `health`
The skill advertises and documents shell and environment-based operations but does not declare any explicit tool scope such as allowed-tools or permissions. That mismatch weakens least-privilege controls and can cause the agent to invoke broader capabilities than a reviewer or runtime policy would expect, especially for a skill that performs administrative actions against infrastructure.
The description is broad enough to trigger on general Proxmox-related conversation, not just explicit requests to administer a cluster. In an agent setting, ambiguous activation boundaries can cause the skill to engage during informational discussions and then expose credentials, enumerate infrastructure, or suggest/perform sensitive commands without sufficiently clear user intent.
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.
Comprehensive Proxmox VE management combining:
- **Power control**: Start, stop, reboot, shutdown VMs/containers
- **Snapshots**: Create, list, delete, rollback (with optional RAM state)
- **Backups**: List and create backups
- **Storage**: View storage pools and content
- **Tasks**: Track async operations and logs
- **Cluster overview**: Nodes, resources, health
The example credential configuration sets verify_ssl to false with no warning. Disabling TLS certificate verification enables man-in-the-middle interception of API traffic and token theft, which is especially dangerous because this skill manages hypervisor infrastructure and can perform high-impact administrative actions.
The environment variable example explicitly sets PVE_VERIFY_SSL="false" without any caution. This normalizes insecure transport settings and can lead operators to send authentication tokens over connections that do not validate the server identity, exposing cluster administration to interception.
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
PROXMOX_TOKEN_ID=clawd@pve!tokenname PROXMOX_TOKEN_SECRET=your-token-secret EOF chmod 600 ~/.proxmox-credentials
### Create API Token
The notes recommend using -k or disabling SSL verification without warning that it is insecure. For an API-driven infrastructure management skill, this materially increases the chance of credential compromise and unauthorized administrative control through spoofed endpoints or network interception.
The script executes destructive infrastructure actions like stop, shutdown, delete_snapshot, and rollback immediately based on command-line arguments, with no confirmation, dry-run mode, or secondary safety check. In the context of a Proxmox administration skill, this is more dangerous because a mistaken invocation or prompt-influenced agent action can directly disrupt workloads, cause downtime, or revert systems to unsafe states.
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.
PROXMOX_HOST="${PROXMOX_HOST#https://}"
PROXMOX_HOST="https://${PROXMOX_HOST}"
: "${PROXMOX_HOST:?Set PROXMOX_HOST or create ~/.openclaw/credentials/proxmox.json}"
: "${PROXMOX_TOKEN_ID:?Set PROXMOX_TOKEN_ID}"
: "${PROXMOX_TOKEN_SECRET:?Set PROXMOX_TOKEN_SECRET}"
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.
delsnap <vmid> <snap> Delete snapshot
backups <node> [storage] List backups
backup <vmid> [storage] Create backup
storage <node> List storage pools
content <node> [storage] List storage content
Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.
return p.cluster.resources.get(type="vm")
def status_current(p: ProxmoxAPI, node: str, kind: str, vmid: str):
endpoint = getattr(p.nodes(node), kind)
return endpoint(vmid).status.current.get()
def action_vm(p: ProxmoxAPI, node: str, kind: str, vmid: str, action: str):
Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.
return p.cluster.resources.get(type="vm")
def status_current(p: ProxmoxAPI, node: str, kind: str, vmid: str):
endpoint = getattr(p.nodes(node), kind)
return endpoint(vmid).status.current.get()
def action_vm(p: ProxmoxAPI, node: str, kind: str, vmid: str, action: str):
Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.
return p.cluster.resources.get(type="vm")
def status_current(p: ProxmoxAPI, node: str, kind: str, vmid: str):
endpoint = getattr(p.nodes(node), kind)
return endpoint(vmid).status.current.get()
def action_vm(p: ProxmoxAPI, node: str, kind: str, vmid: str, action: str):
Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.
return p.cluster.resources.get(type="vm")
def status_current(p: ProxmoxAPI, node: str, kind: str, vmid: str):
endpoint = getattr(p.nodes(node), kind)
return endpoint(vmid).status.current.get()
def action_vm(p: ProxmoxAPI, node: str, kind: str, vmid: str, action: str):
Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.
return p.cluster.resources.get(type="vm")
def status_current(p: ProxmoxAPI, node: str, kind: str, vmid: str):
endpoint = getattr(p.nodes(node), kind)
return endpoint(vmid).status.current.get()
def action_vm(p: ProxmoxAPI, node: str, kind: str, vmid: str, action: str):
Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.
return p.cluster.resources.get(type="vm")
def status_current(p: ProxmoxAPI, node: str, kind: str, vmid: str):
endpoint = getattr(p.nodes(node), kind)
return endpoint(vmid).status.current.get()
def action_vm(p: ProxmoxAPI, node: str, kind: str, vmid: str, action: str):
This line dynamically invokes an action method on the guest status object using unvalidated input. If the callable surface exposed by proxmoxer changes or includes additional state-changing methods, an attacker or mistaken caller could trigger unintended operations beyond the documented start/stop/reboot/shutdown set, which is especially risky in an infrastructure-management skill.
def action_vm(p: ProxmoxAPI, node: str, kind: str, vmid: str, action: str):
endpoint = getattr(p.nodes(node), kind)
return getattr(endpoint(vmid).status, action).post()
def snapshot_vm(p: ProxmoxAPI, node: str, kind: str, vmid: str, snapname: str, vmstate: bool = False):
endpoint = getattr(p.nodes(node), kind)
No suspicious patterns detected.