Back to skill

Security audit

Self-Host Deployer

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent VPS self-hosting guide, but it asks for privileged access and includes several unsafe default deployment patterns that warrant careful review before use.

Install only if you are comfortable reviewing and tightening the generated deployment steps. Do not paste SSH passwords or private keys into chat; use a temporary least-privileged deployment account or out-of-band secret handling. Before running commands, remove unnecessary Docker socket mounts, bind admin interfaces to localhost or VPN, pin images and installers, validate all domain/app/path values, and approve any cron job explicitly.

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
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
Findings (6)

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:974
Finding

Unverified Remote Installer Executes with Administrative Privileges

Content
View full analysis
Remediation
View remediation
" "coolify-install.sh" | sha256sum -c - less coolify-install.sh sudo bash coolify-install.sh ``` ]]>

T06 · System Persistence

Error
Location
SKILL.md:1242
Finding

Privileged Persistent Backup Task Is Installed Without Adequate Hardening

Content
View full analysis
/opt/backups/backup-${APP_NAME}.sh << 'BACKUPEOF' #!/bin/bash set -euo pipefail BACKUP_DIR="/opt/backups/${APP_NAME}" TIMESTAMP=$(date +%Y%m%d_%H%M%S) RETENTION_DAYS=30 mkdir -p "$BACKUP_DIR" # === Postgres Backup (if applicable) === docker exec ${APP_NAME}-db pg_dumpall -U ${DB_USER} | gzip > "$BACKUP_DIR/db_${TIMESTAMP}.sql.gz" # === MySQL Backup (Ghost only) === # docker exec ghost-db mysqldump -u ghost -p${DB_PASSWORD} ghost | gzip > "$BACKUP_DIR/db_${TIMESTAMP}.sql.gz" # === Volume Backup === # Stop app briefly for consistent backup (optional — skip for near-zero-downtime) # docker compose -f /opt/${APP_NAME}/docker-compose.yml stop ${APP_NAME} tar czf "$BACKUP_DIR/volumes_${TIMESTAMP}.tar.gz" -C /var/lib/docker/volumes . --include="${APP_NAME}*" # docker compose -f /opt/${APP_NAME}/docker-compose.yml start ${APP_NAME} # === SQLite Backup (Vaultwarden, Uptime Kuma) === # docker exec ${APP_NAME} sqlite3 /data/db.sqlite3 ".backup '/data/backup.sqlite3'" # docker cp ${APP_NAME}:/data/backup.sqlite3 "$BACKUP_DIR/db_${TIMESTAMP}.sqlite3" # === Cleanup old backups === find "$BACKUP_DIR" -type f -mtime +${RETENTION_DAYS} -delete echo "[$(date)] Backup complete: $BACKUP_DIR/*_${TIMESTAMP}*" BACKUPEOF chmod +x /opt/backups/backup-${APP_NAME}.sh # Add to crontab — daily at 3 AM (crontab -l 2>/dev/null; echo "0 3 * * * /opt/backups/backup-${APP_NAME}.sh >> /var/log/backup-${APP_NAME}.log 2>&1") | crontab - ``` ### Technical Analysis The Skill registers a daily cron job that survives completion of the deployment session. Scheduled backups are consistent with the declared functionality, so the persistence mechanism is not inherently a backdoor. However, the implementation does not: - Request explicit approval before installing persistent execution. - Specify or enforce the accou ...[truncated 1434 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:1148
Finding

Unvalidated Deployment Values Are Interpolated into Privileged Shell Commands

Content
View full analysis
/etc/nginx/sites-available/${APP_NAME} << 'NGINXEOF' ``` ```bash ln -sf /etc/nginx/sites-available/${APP_NAME} /etc/nginx/sites-enabled/ nginx -t && systemctl reload nginx ``` ```bash certbot --nginx -d ${DOMAIN} --non-interactive --agree-tos -m ${EMAIL} ``` ```bash cat > /opt/backups/backup-${APP_NAME}.sh << 'BACKUPEOF' ... BACKUP_DIR="/opt/backups/${APP_NAME}" ... docker exec ${APP_NAME}-db pg_dumpall -U ${DB_USER} | gzip > "$BACKUP_DIR/db_${TIMESTAMP}.sql.gz" ... BACKUPEOF chmod +x /opt/backups/backup-${APP_NAME}.sh (crontab -l 2>/dev/null; echo "0 3 * * * /opt/backups/backup-${APP_NAME}.sh >> /var/log/backup-${APP_NAME}.log 2>&1") | crontab - ``` ```bash mkdir -p /opt/${APP_NAME} cd /opt/${APP_NAME} ``` ```bash curl -f http://localhost:${APP_PORT}/${HEALTH_ENDPOINT} curl -f https://${DOMAIN}/${HEALTH_ENDPOINT} ``` ### Technical Analysis Values gathered from the user or derived during deployment—including application name, domain, email, port, database user, and health endpoint—are inserted into privileged paths, command arguments, generated shell scripts, cron content, URLs, and Nginx configuration without documented validation. Several expansions are unquoted. Crafted whitespace, shell metacharacters, path traversal sequences, leading option characters, command substitutions, or newline characters can alter command behavior. Even where a here-document delimiter is quoted, the generated script itself contains unresolved placeholders whose eventual substitution method is unspecified and may remain unsafe. Domain and related values can also affect generated Nginx syntax or command-line option parsing. Because these operations modify `/etc`, `/opt`, cron, and system services, unsafe interpolation occurs in a privileged execution context. ### Attack Path 1 ...[truncated 1247 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
SKILL.md:324
Finding

Docker Socket Mounts Grant Containers Host-Equivalent Administrative Access

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Error
Location
SKILL.md:850
Finding

Mutable and Unverified Third-Party Dependencies Create Supply-Chain Exposure

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:1033
Finding

Nginx Proxy Manager Administration Port Is Publicly Bound with Known Default Credentials

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
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (25)

Ssd 3

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The skill explicitly instructs the agent to request highly sensitive SSH credentials as part of normal operation. In this context, that is especially dangerous because the same skill also performs root-level administrative actions, so exposed credentials could immediately enable full VPS compromise.

Content

No source excerpt is available for this finding.

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

cd /opt/supabase/docker

Copy and configure environment

cp .env.example .env

text

**Critical `.env` changes:**

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

cd /opt/supabase/docker

Copy and configure environment

cp .env.example .env

text

**Critical `.env` changes:**

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

cd /opt/supabase/docker

Copy and configure environment

cp .env.example .env

text

**Critical `.env` changes:**

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

cd /opt/supabase/docker

Copy and configure environment

cp .env.example .env

text

**Critical `.env` changes:**

Docker Socket Access

High
Category
Privilege Escalation
Confidence
98% confidence
Finding

Mounting /var/run/docker.sock into Uptime Kuma gives the container direct access to the Docker daemon, which can enable effective host control or sensitive metadata exposure. Even if presented as optional monitoring, including it in the default template makes a high-risk privilege escalation path easy to adopt unintentionally.

Content

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

md
- "127.0.0.1:3001:3001"
    volumes:
      - uptime-kuma-data:/app/data
      - /var/run/docker.sock:/var/run/docker.sock:ro
    healthcheck:
      test: ["CMD-SHELL", "extra/healthcheck"]
      interval: 30s

External Script Fetching

High
Category
Supply Chain
Confidence
99% confidence
Finding

The skill instructs users to fetch and execute a remote install script for Coolify via curl piped directly to bash. This pattern bypasses review and integrity controls; if the remote script, transport, or supply chain is compromised, it can execute arbitrary code on the VPS with full privileges.

Content

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

external: true

text

**Health check:** `curl -f http://localhost:8000/api/`

---

Chaining Abuse

High
Category
Tool Misuse
Confidence
99% confidence
Finding

Using '| bash' to immediately execute fetched content is a classic dangerous command-chaining pattern that can turn a network or supply-chain compromise into instant remote code execution. In this skill, the risk is amplified because the workflow is explicitly about making administrative host changes.

Content

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

Gotchas: Coolify manages its own Docker setup. Use the official install script instead of manual compose.

bash
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash

Coolify will be available at http://<VPS_IP>:8000. It handles its own reverse proxy, SSL, and database deployment.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The Portainer and Dockge templates mount /var/run/docker.sock, which effectively grants root-equivalent control over the Docker daemon and, by extension, the host. Any compromise of those applications, misconfiguration, or unsafe agent action could lead to container creation, filesystem mounts, secret extraction, or full host takeover.

Content

No source excerpt is available for this finding.

Docker Socket Access

High
Category
Privilege Escalation
Confidence
99% confidence
Finding

Portainer with direct Docker socket access has near-total control over the host container environment, including creating privileged containers and mounting host filesystems. In a skill that auto-generates deployment steps, this represents a severe capability expansion and host-compromise risk.

Content

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

md
ports:
      - "127.0.0.1:9443:9443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer-data:/data
    healthcheck:
      test: ["CMD-SHELL", "curl -fk https://localhost:9443/api/system/status || exit 1"]

Docker Socket Access

High
Category
Privilege Escalation
Confidence
99% confidence
Finding

Dockge is also granted direct Docker socket access, which allows stack and container management with root-equivalent host impact. A compromise of the app or misuse of the generated deployment could therefore lead to full control of the VPS.

Content

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

md
ports:
      - "127.0.0.1:5001:5001"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - dockge-data:/app/data
      - /opt/stacks:/opt/stacks
    environment:

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The trigger phrases are broad and include generic language like 'self-host' and 'deploy X', which can cause the skill to activate for common requests not specifically intended for this powerful deployment workflow. In a skill that requests credentials and performs host changes, overbroad activation materially increases the chance of unsafe or unintended use.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The usage guidance says to use the skill when users say generic phrases such as 'deploy X' or 'host my own X', which is ambiguous and can overlap with unrelated deployment needs. Because the skill later asks for privileged access and prescribes impactful system changes, accidental routing into this workflow becomes security-relevant.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The catalog includes infrastructure-management tools such as Nginx Proxy Manager, Portainer, and Dockge that provide broad control over networking, containers, and stack lifecycle beyond narrowly deploying a single self-hosted application. In this skill context, that expanded scope increases blast radius if the skill is auto-invoked or misused, because the agent may steer users toward tools that expose host-level operational control.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
95% confidence
Finding

The skill requests root or sudo-level access to the VPS, enabling powerful system modification. While administrative access is often needed for deployment, asking for it directly in an agent skill without strong controls magnifies the consequences of agent error, compromise, or credential leakage.

Content

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

md
Ask the user for:

1. **VPS IP address** and **SSH credentials** (root or sudo user)
2. **Domain/subdomain** for the app (e.g., `analytics.example.com`)
3. **Email address** for SSL certificate registration (Certbot)
4. Any **app-specific settings** (see gotchas per app below)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill instructs the agent to ask for SSH credentials directly, but provides no privacy warning, secure handling guidance, or safer alternative. Requesting root or sudo credentials in plain conversational flow creates a high risk of secret exposure, storage in logs, or misuse by an over-privileged agent.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The Uptime Kuma template mounts the Docker socket for optional monitoring, giving the container privileged visibility into host containers that is not necessary for basic uptime checks. Even read-only socket access can reveal sensitive metadata and may still enable meaningful abuse depending on daemon behavior and surrounding tooling.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The Paperless-ngx template forces PAPERLESS_OCR_LANGUAGE: eng, and the skill does not ask the user to choose OCR language or justify why English is required. This is a natural-language locale policy issue because it imposes a language setting by default without opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The Stirling PDF template sets LANGS=en_US, which hard-codes a specific language/locale without asking the user which language they want. This violates the policy against forcing a language choice when no opt-in is provided.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

external: true

text

**Health check:** `curl -fk https://localhost:9443/api/system/status`

---

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

These sections direct significant host modifications including package installation, Nginx reconfiguration, certificate issuance, file writes under /etc and /opt, Docker deployment, and cron persistence, but there is no up-front warning about the operational and security impact. In a deployment skill, omitting a clear warning makes it easier for users to authorize destructive or persistent changes without informed consent.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
91% confidence
Finding

The backup setup installs a recurring cron job, creating persistent scheduled execution on the host. Persistence is not inherently malicious in an admin workflow, but doing it automatically without explicit consent or visibility increases operational and security risk if the script is later modified or mishandled.

Content

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

chmod +x /opt/backups/backup-${APP_NAME}.sh

Add to crontab — daily at 3 AM

(crontab -l 2>/dev/null; echo "0 3 * * * /opt/backups/backup-${APP_NAME}.sh >> /var/log/backup-${APP_NAME}.log 2>&1") | crontab -

text

---

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% 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 1331)May include surrounding context.

md
- [ ] Default passwords changed
- [ ] Signups disabled (if applicable — Vaultwarden, Gitea)
- [ ] Email/SMTP configured (if applicable — Ghost, n8n)
- [ ] Backup cron is running (`crontab -l`)
- [ ] Firewall only exposes ports 80, 443, and SSH (`ufw status`)
- [ ] Docker auto-updates considered (Watchtower or manual update schedule)
- [ ] Monitoring set up (deploy Uptime Kuma if not already running)

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The n8n template defaults GENERIC_TIMEZONE to America/New_York, which imposes a locale-specific setting if the user does not override it. The skill does not ask for timezone preference before applying this US-centric default.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The Paperless-ngx template defaults PAPERLESS_TIME_ZONE to America/New_York, which applies a specific locale absent user selection. No user-choice step in the skill collects timezone preference before using this default.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.