T09 · Insecure Skill Coding Practices
- Location
scripts/vultr.py:310- Finding
User Password Exposed Through Command-Line Arguments
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This is a real Vultr cloud-management skill, but it gives an agent broad account-changing and credential-retrieval power without built-in confirmations or tight scoping.
Install only if you are comfortable giving the agent broad Vultr account authority. Use a least-privilege Vultr API key where possible, avoid running destructive commands from ambiguous prompts, do not save kubeconfig files in shared workspaces, and treat --password, kubeconfig, regenerated object-storage keys, and the API key as sensitive secrets.
scripts/vultr.py:310User Password Exposed Through Command-Line Arguments
scripts/vultr.py:68Unsafe Construction of Query Strings and URL Path Components
Referenced artifact was not completely inspected
python3 scripts/vultr.py <resource> <action> [options]
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
vultr.py kubernetes list # List clusters
vultr.py kubernetes create --region ewr --version v1.28 --label my-cluster
vultr.py kubernetes kubeconfig --id abc123 # Get kubeconfig
vultr.py kubernetes versions # Available versions
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
vultr.py kubernetes list # List clusters
vultr.py kubernetes create --region ewr --version v1.28 --label my-cluster
vultr.py kubernetes kubeconfig --id abc123 # Get kubeconfig
vultr.py kubernetes versions # Available versions
The workflow explicitly writes kubeconfig to a local file without any warning that the file contains cluster credentials. In agent or shared environments, saving access material to disk can create credential leakage through workspace persistence, later tool access, backups, or logs.
--version v1.28.0
--label "prod-cluster"
vultr.py kubernetes kubeconfig --id cluster-id > kubeconfig
The example redirects kubeconfig output into a persistent file named kubeconfig, creating a tangible credential artifact on disk. That increases the attack surface because subsequent processes, users, or tooling may read the file and obtain cluster access.
--label "prod-cluster"
vultr.py kubernetes kubeconfig --id cluster-id > kubeconfig
### Set Up Managed Database
The parser advertises a kubeconfig retrieval action, which signals that the skill can access cluster credentials capable of administering Kubernetes resources. In a general-purpose agent context, exposing credential-retrieval functionality materially increases the risk of secret disclosure and downstream cluster compromise.
# Kubernetes
k8s_parser = subparsers.add_parser("kubernetes", help="Kubernetes clusters (VKE)")
k8s_parser.add_argument("action", choices=["list", "get", "create", "update", "delete", "kubeconfig", "versions", "node-pools"])
k8s_parser.add_argument("--id", help="Cluster ID")
k8s_parser.add_argument("--region", help="Region ID")
k8s_parser.add_argument("--label", help="Cluster label")
The script exposes full user-management operations, including create, update, and delete of account users, which is a highly sensitive administrative capability. In an agent/skill context, this expands the blast radius from infrastructure management into identity administration, enabling unauthorized account changes or persistence if invoked through prompt manipulation or insufficient authorization checks.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
parser.print_help()
sys.exit(1)
# Get API key from config file
api_key = get_api_key()
client = VultrClient(api_key)
This code actually performs the kubeconfig fetch from the Vultr API and returns the result for printing, which can expose cluster access credentials directly to the caller. If misused, an attacker or compromised agent session could obtain administrative access to Kubernetes clusters and pivot into workloads, secrets, and networked systems.
return client.put(f"/kubernetes/clusters/{args.id}", data)
elif action == "delete":
return client.delete(f"/kubernetes/clusters/{args.id}")
elif action == "kubeconfig":
return client.get(f"/kubernetes/clusters/{args.id}/kubeconfig")
elif action == "versions":
return client.get("/kubernetes/versions")
The surrounding flow confirms the kubeconfig endpoint is directly reachable through normal command routing, with no additional safeguards. That makes credential access operationally easy and therefore more dangerous in an autonomous or semi-autonomous toolchain.
elif action == "delete":
return client.delete(f"/kubernetes/clusters/{args.id}")
elif action == "kubeconfig":
return client.get(f"/kubernetes/clusters/{args.id}/kubeconfig")
elif action == "versions":
return client.get("/kubernetes/versions")
elif action == "node-pools":
The skill documents networked API access and local credential file reads but does not declare any explicit tool scope or permissions boundary. In an agent environment, that omission can allow the skill to be invoked without clear operator understanding of its ability to access local secrets and perform live cloud actions, increasing the chance of unintended infrastructure changes.
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.
Store your API key in ~/.config/vultr/api_key:
mkdir -p ~/.config/vultr
echo -n "YOUR_API_KEY" > ~/.config/vultr/api_key
chmod 600 ~/.config/vultr/api_key
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
mkdir -p ~/.config/vultr
echo -n "YOUR_API_KEY" > ~/.config/vultr/api_key
chmod 600 ~/.config/vultr/api_key
Generate API keys at: https://my.vultr.com/settings/#settingsapi
The skill includes create, delete, attach, and billing-related operations for cloud resources without an upfront warning that actions may be destructive or incur real charges. In an autonomous or semi-autonomous agent setting, this raises the risk of accidental deletion, service disruption, or unexpected spend from ordinary user prompts.
The file instructs users to pass an API key in the Authorization header and provides the key-generation location, but it does not warn that the key is a sensitive credential that must not be logged, shared, or committed. Because this markdown describes behavior affecting account security and privacy, a user warning is expected.
This markdown file describes operations that can create, delete, reinstall, and expose instance data, including deleting instances, reinstalling systems, and retrieving user data, but it does not include any warning about impact on user data or service availability. Under the markdown-file criteria, documentation should warn about behaviors that could affect privacy, system integrity, or irreversible state changes.
The manifest describes a skill for managing Vultr infrastructure resources such as instances, networking, storage, billing, and related cloud objects. This reference also includes full /users management endpoints, which are account/identity administration capabilities not mentioned in the manifest description and materially broaden the skill's implied behavior.
The manifest says the skill handles instances, bare-metal, kubernetes, databases, load-balancers, dns, firewall, vpc, snapshots, ssh-keys, block-storage, object-storage, reserved-ips, and billing. However, the file documentation and implementation also expose tickets, users, startup scripts, applications, OS listings, ISO images, backups, regions, and plans, including user-management actions that are materially broader than the declared scope.
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.
vultr.py account get
vultr.py instances list
vultr.py instances get --id abc123
vultr.py instances create --region ewr --plan vc2-1c-1gb --os 174
vultr.py instances start --id abc123
vultr.py dns list
vultr.py dns records --domain example.com
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import urllib.error
from typing import Any, Dict, List, Optional
API_BASE = "https://api.vultr.com/v2"
def get_api_key():
The client exposes numerous destructive and high-impact actions—such as delete, reinstall, reboot, detach, close, and key regeneration—without any confirmation prompt, dry-run mode, or risk acknowledgment. In an agent-driven environment, this creates a serious risk of irreversible infrastructure changes from ambiguous prompts, prompt injection, or operator error.
Regenerating object-storage keys is a credential-rotation operation that can invalidate existing access and issue new secrets, making it security-sensitive beyond ordinary storage management. In an agent setting, accidental or unauthorized invocation could disrupt services and facilitate takeover of storage access paths if new credentials are exposed downstream.
The manifest lists infrastructure and billing operations, but does not mention customer support workflows. Documenting ticket creation, closing, and replying expands the skill from infrastructure management into support-account interactions, which is a separate capability from the stated purpose.
The manifest explicitly enumerates many managed resource types, but does not include startup scripts among them. This documentation suggests the skill may create and modify reusable account-level automation artifacts beyond the resources it claims to handle.
No suspicious patterns detected.