Back to skill

Security audit

VPS Deploy

Security checks for vulnerabilities and agentic risk

Overview

This is a real VPS deployment guide, but it asks for broad permanent root-level server changes that could expose or break a server if run as written.

Review carefully before installing. Use only on a fresh or dedicated VPS, require explicit confirmation before SSH, firewall, Nginx, or destructive changes, replace curl-to-shell Docker installation with a verified package workflow, use a dedicated deploy public key instead of copying root authorized_keys, avoid unrestricted passwordless sudo, and back up Nginx configs before changes.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (4)

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:91
Finding

Unverified Remote Script Executed with Root Privileges

Content
View full analysis
Remediation
View remediation
/root/get-docker.sh" | sha256sum -c - less /root/get-docker.sh sh /root/get-docker.sh rm -f /root/get-docker.sh ``` A digest is useful only if it comes from a separate trusted source and is pinned before retrieval. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
SKILL.md:56
Finding

Deploy Account Receives Multiple Unrestricted Root-Equivalent Privileges

Content
View full analysis
> /etc/sudoers.d/deploy ``` ```bash curl -fsSL https://get.docker.com | sh usermod -aG docker deploy ``` ### Technical Analysis The deployment account is placed in both the `sudo` and `docker` groups and receives an unrestricted `NOPASSWD:ALL` sudoers rule. The sudoers rule permits the account to execute any command as any user, including root, without another authentication step. Docker group membership is independently root-equivalent on a conventional rootful Docker installation because a member can start privileged containers, mount the host filesystem, access sensitive host paths, or interact with the Docker daemon. The Skill therefore creates two separate unrestricted privilege-escalation paths. These privileges exceed what is minimally necessary to upload an application and request a controlled deployment operation. ### Attack Path #### Passwordless sudo path 1. An attacker obtains access to the `deploy` account through a stolen SSH key, compromised administrator workstation, or other account compromise. 2. The attacker logs in as `deploy`. 3. The attacker runs an arbitrary command through unrestricted sudo, such as a root shell. 4. No password or secondary approval is required. 5. The attacker obtains complete administrative control of the server. #### Docker group path 1. An attacker obtains access to the `deploy` account. 2. The attacker communicates with the root-owned Docker daemon through Docker group permissions. 3. The attacker launches a container that mounts the host root filesystem or otherwise requests privileged host access. 4. The attacker modifies host files or executes commands in the host s ...[truncated 702 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
SKILL.md:64
Finding

Root SSH Authorization Is Duplicated into a Root-Equivalent Deployment Account

Content
View full analysis
/dev/null || true chown -R deploy:deploy /home/deploy/.ssh chmod 700 /home/deploy/.ssh chmod 600 /home/deploy/.ssh/authorized_keys 2>/dev/null || true ``` ### Technical Analysis The procedure copies the complete `authorized_keys` file of the current root account into the new deployment account without reviewing individual keys or their intended principals. Copying public authorization entries does not expose private keys by itself. However, it grants every holder of a root-authorized private key access to the new account. Because the same Skill grants the deployment account unrestricted passwordless sudo and Docker daemon access, every copied key retains root-equivalent control through an additional username. This undermines least privilege and makes trust revocation more difficult. Root authorization files can include old administrator keys, emergency access keys, shared automation keys, or key-specific restrictions that may not be appropriate for deployment access. The `|| true` behavior can also conceal a failed key migration while subsequent SSH hardening proceeds. ### Attack Path 1. A root `authorized_keys` file contains an old, shared, automation, or otherwise unintended public key. 2. The Skill copies the entire file into `/home/deploy/.ssh/authorized_keys`. 3. The holder of the corresponding private key logs in as `deploy`. 4. The holder invokes unrestricted passwordless sudo or abuses Docker group membership. 5. The holder obtains complete root-equivalent access through the deployment account. 6. Removing the key from root’s authorization file alone does not revoke access because a duplicate remains under the deploy account. ### Impact Assessment ...[truncated 592 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:184
Finding

Unvalidated Deployment Values Are Interpolated into Privileged Shell Commands and Configuration Paths

Content
View full analysis
"mkdir -p ~/apps/" # Copy project files (exclude node_modules, .git, etc.) rsync -avz --exclude='node_modules' --exclude='.git' --exclude='.next' \ ./ deploy@:~/apps// ``` ```bash ssh deploy@ "cd ~/apps/ && docker compose up -d --build" ``` ```bash # Generate site config cat > /etc/nginx/sites-available/ << 'EOF' server { listen 80; server_name ; location / { proxy_pass http://127.0.0.1:; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_cache_bypass $http_upgrade; proxy_read_timeout 86400; } } EOF ln -sf /etc/nginx/sites-available/ /etc/nginx/sites-enabled/ rm -f /etc/nginx/sites-enabled/default nginx -t && systemctl reload nginx ``` ```bash apt install -y certbot python3-certbot-nginx certbot --nginx -d --non-interactive --agree-tos -m ``` ### Technical Analysis The instructions embed values such as the VPS address, application name, domain, application port, and email directly into: - Local shell commands. - Remote SSH command strings. - Filesystem paths. - Nginx configuration. - Certbot command-line arguments. The Skill does not require strict validation or context-specific escaping before substitution. Shell metacharacters, whitespace, option prefixes, path separators, traversal sequences, or Nginx configuration tokens could change the meaning of a generated command or configuration. The risk is par ...[truncated 1949 chars]
Remediation
View remediation
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • 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 (16)

Credential Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

Creating /home/deploy/.ssh as part of an automated flow is not inherently dangerous, but in this context it is directly tied to populating the directory with root's authorized_keys. That workflow expands access to a new account without explicit user-controlled key enrollment and can unintentionally propagate privileged access.

Content

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

bash
# Copy root's authorized_keys to deploy user
mkdir -p /home/deploy/.ssh
cp ~/.ssh/authorized_keys /home/deploy/.ssh/ 2>/dev/null || true
chown -R deploy:deploy /home/deploy/.ssh
chmod 700 /home/deploy/.ssh
chmod 600 /home/deploy/.ssh/authorized_keys 2>/dev/null || true

Credential Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

Creating /home/deploy/.ssh as part of an automated flow is not inherently dangerous, but in this context it is directly tied to populating the directory with root's authorized_keys. That workflow expands access to a new account without explicit user-controlled key enrollment and can unintentionally propagate privileged access.

Content

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

bash
# Copy root's authorized_keys to deploy user
mkdir -p /home/deploy/.ssh
cp ~/.ssh/authorized_keys /home/deploy/.ssh/ 2>/dev/null || true
chown -R deploy:deploy /home/deploy/.ssh
chmod 700 /home/deploy/.ssh
chmod 600 /home/deploy/.ssh/authorized_keys 2>/dev/null || true

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
cp ~/.ssh/authorized_keys /home/deploy/.ssh/ 2>/dev/null || true
chown -R deploy:deploy /home/deploy/.ssh
chmod 700 /home/deploy/.ssh
chmod 600 /home/deploy/.ssh/authorized_keys 2>/dev/null || true

# Harden SSH config
sed -i 's/#\?PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
cp ~/.ssh/authorized_keys /home/deploy/.ssh/ 2>/dev/null || true
chown -R deploy:deploy /home/deploy/.ssh
chmod 700 /home/deploy/.ssh
chmod 600 /home/deploy/.ssh/authorized_keys 2>/dev/null || true

# Harden SSH config
sed -i 's/#\?PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config

Chaining Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Piping downloaded content directly into sh is a classic dangerous command-chaining pattern because it combines retrieval and execution in one step, eliminating validation checkpoints. Since this occurs during privileged server setup, any malicious or corrupted response becomes immediate root command execution.

Content

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

2e. Install Docker

bash
curl -fsSL https://get.docker.com | sh
usermod -aG docker deploy

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
restart: unless-stopped
    ports:
      - "127.0.0.1:${APP_PORT:-3000}:${APP_PORT:-3000}"
    env_file: .env
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:${APP_PORT:-3000}/"]
      interval: 30s

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
88% confidence
Finding

The command unconditionally removes /etc/nginx/sites-enabled/default, which is a destructive host-level change. In context, this deployment skill may be used on non-fresh servers, so deleting an existing site definition without backup or confirmation can break unrelated services or remove an intentionally configured default vhost.

Content

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

EOF

ln -sf /etc/nginx/sites-available/ /etc/nginx/sites-enabled/ rm -f /etc/nginx/sites-enabled/default nginx -t && systemctl reload nginx

text

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill metadata includes broad trigger phrases like 'set up my server' and 'deploy to production', which can cause the skill to activate for requests that may not actually intend full VPS reconfiguration. Because this skill performs sensitive server-hardening and deployment actions, accidental invocation materially increases the risk of destructive or over-privileged operations.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

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

md
## Prerequisites

- SSH access to a VPS (IP address + root or sudo credentials)
- A domain pointed to the VPS IP (for SSL — can skip SSL if no domain)
- The app must have a Dockerfile or be deployable via Docker

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
97% confidence
Finding

The skill grants the 'deploy' user passwordless sudo for all commands via NOPASSWD:ALL, which creates a permanently over-privileged account. If that account or its SSH key is compromised, an attacker gains immediate full-root control of the server without additional barriers.

Content

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

2b. Create Deploy User

bash
adduser --disabled-password --gecos "" deploy
usermod -aG sudo docker deploy
echo "deploy ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/deploy

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 68)May include surrounding context.

md
mkdir -p /home/deploy/.ssh
cp ~/.ssh/authorized_keys /home/deploy/.ssh/ 2>/dev/null || true
chown -R deploy:deploy /home/deploy/.ssh
chmod 700 /home/deploy/.ssh
chmod 600 /home/deploy/.ssh/authorized_keys 2>/dev/null || true

# Harden SSH config

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 69)May include surrounding context.

md
cp ~/.ssh/authorized_keys /home/deploy/.ssh/ 2>/dev/null || true
chown -R deploy:deploy /home/deploy/.ssh
chmod 700 /home/deploy/.ssh
chmod 600 /home/deploy/.ssh/authorized_keys 2>/dev/null || true

# Harden SSH config
sed -i 's/#\?PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill's safety rules explicitly require backing up existing Nginx configs before overwriting, but the operational steps write a new site config, replace the enabled symlink, and remove the default site without any backup. In a production deployment skill, this can break an existing web stack or cause accidental service disruption, especially if run on a server already hosting applications.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
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.

Content

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

md
## Safety Rules

- **NEVER** disable the firewall without asking
- **NEVER** expose database ports to the internet
- **ALWAYS** verify SSH access with the deploy user BEFORE disabling root login
- **ALWAYS** back up existing Nginx configs before overwriting

Vague Triggers

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The 'When to Use' section contains ambiguous phrases such as 'go to production' and 'set up my server' without enough scoping to a new VPS or dedicated host. In context, that ambiguity is risky because the skill includes firewall, SSH, Nginx, and Docker changes that may be inappropriate for shared or pre-existing environments.

Content

No source excerpt is available for this finding.

External Script Fetching

Low
Category
Supply Chain
Confidence
94% confidence
Finding

Fetching and executing a remote install script with curl directly into sh removes an opportunity for inspection, integrity verification, or pinning to a trusted package source. In a root-level VPS setup flow, compromise of the upstream script, transport path, or unexpected script changes would immediately grant arbitrary code execution as root.

Content

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

2e. Install Docker

bash
curl -fsSL https://get.docker.com | sh
usermod -aG docker deploy

Static analysis

No suspicious patterns detected.