Back to skill

Security audit

Bot Status API

Security checks across malware telemetry and agentic risk

Overview

This appears to be a real monitoring API, but it needs careful review because it exposes detailed local status while running shell checks and weakening HTTPS security by default.

Install only as a private, trusted monitoring service. Keep it bound to localhost or behind strong authentication, do not expose /status publicly, use only administrator-controlled config and trusted skill directories, avoid command checks where possible, run it under a low-privilege account, and remove or narrow the global TLS verification bypass before production use.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • 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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (15)

Lp3

Medium
Category
MCP Least Privilege
Confidence
81% confidence
Finding
The skill describes an HTTP status service that performs network checks and reads environment-adjacent runtime/system state, but the skill metadata does not declare corresponding permissions or clearly surface that capability. Undeclared capabilities reduce user visibility and informed consent, which is a security issue even if the feature is intended for legitimate monitoring.

Context-Inappropriate Capability

Medium
Confidence
91% confidence
Finding
The collector reads a sensitive authentication file to infer whether a token exists, which exceeds what a lightweight status endpoint typically needs and unnecessarily expands the skill's access to secrets-adjacent data. Even though it does not return the token itself, touching credential storage increases blast radius: path misconfiguration, future code changes, error leakage, or reuse of this access pattern could expose secret material or enable credential-state reconnaissance.

Context-Inappropriate Capability

Medium
Confidence
98% confidence
Finding
The collector builds a shell command with config-derived input (`processGrep`) and executes it via `exec`, which invokes a shell. Although the grep value is wrapped in single quotes, an attacker can break out of the quoting with a single quote and inject arbitrary shell syntax, leading to command execution in the context of the monitoring process. In a status API skill, configuration may be treated as trusted operational input, but this context actually increases risk because monitoring components are often deployed broadly and run with access to sensitive host information.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The collector executes `acct.command` via `child_process.exec`, which invokes a shell and allows arbitrary command execution from configuration. In a status API, this creates a powerful execution surface far beyond simple health checks, and if an attacker can influence config they can run arbitrary OS commands with the agent's privileges.

Context-Inappropriate Capability

Medium
Confidence
96% confidence
Finding
The command check executes `svc.command` through a shell via `exec`, so any untrusted or misconfigured service definition can run arbitrary OS commands with the agent's privileges. In a monitoring skill, this is significantly broader than necessary and can lead to full host compromise, data exfiltration, or destructive actions if config is attacker-controlled or indirectly influenced.

Intent-Code Divergence

Low
Confidence
88% confidence
Finding
The file existence check shells out to `ls ${svc.path}` after `access(svc.path)`, which introduces command injection risk if `svc.path` contains shell metacharacters. It also derives authentication status from filename/output heuristics, which can expose filesystem information and produce misleading security signals in a health endpoint.

Context-Inappropriate Capability

Medium
Confidence
98% confidence
Finding
This is a real command injection risk because values parsed from SKILL.md (`bins`) are concatenated directly into a shell command (`which ${b}`) and executed via `child_process.exec`. Since skill metadata may come from custom/workspace skill directories and must be treated as untrusted, an attacker can place shell metacharacters in a bin name to achieve arbitrary command execution under the privileges of the status API process.

Context-Inappropriate Capability

Medium
Confidence
99% confidence
Finding
The code globally sets NODE_TLS_REJECT_UNAUTHORIZED=0, which disables certificate validation for all outbound HTTPS/TLS connections in the process, not just a narrowly scoped health check. This allows a man-in-the-middle attacker to spoof monitored services and tamper with status data or intercept credentials/tokens used by collectors, making the issue more dangerous in a monitoring skill that may query many internal services.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The README explicitly instructs users to place service paths, credentials, email monitoring settings, and Portainer connection details into a local config while advertising a status API that exposes runtime health, installed skills, system metrics, and service connectivity. Without prominent warnings about authentication, network exposure, response redaction, or secret handling, users may deploy an unauthenticated endpoint that leaks sensitive operational metadata or indirectly exposes credentials through misconfiguration.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill advertises a status API exposing runtime health, service connectivity, cron jobs, skills, dev servers, Docker health, and system metrics over HTTP, but it does not warn that this can disclose sensitive operational and reconnaissance data. If deployed without authentication or network restrictions, the endpoint could help attackers map the environment, identify installed components, observe uptime and model details, and target weaker services.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
This code executes a shell command derived from configuration without any warning, restriction, or disclosure that operator-supplied values can influence shell execution. The lack of guardrails makes unsafe deployment more likely and compounds the command injection risk, especially in a tool marketed as a lightweight status/monitoring API where users may assume configuration fields are harmless. The issue is not just documentation quality; it reflects an unsafe interface design around privileged command execution.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
Passing `{ ...process.env, ...acct.env }` into the subprocess exposes all environment secrets available to the parent process to any configured command. Combined with arbitrary command execution, this can leak API keys, tokens, database credentials, and other sensitive runtime data to local files, logs, or remote exfiltration endpoints.

Missing User Warnings

High
Confidence
98% confidence
Finding
TLS verification is disabled silently and globally, so users deploying the status API may believe HTTPS checks are trustworthy when they are not. In this context, the API aggregates health and connectivity data from potentially sensitive internal endpoints, so silent insecure transport can conceal active interception and produce false health results.

Credential Access

High
Category
Privilege Escalation
Content
accounts.map(async (acct) => {
      const res = await execAsync(acct.command, {
        timeout: acct.timeout || 8000,
        env: { ...process.env, ...acct.env },
      });

      let status = "error";
Confidence
93% confidence
Finding
.env

Unsafe Defaults

Medium
Category
Tool Misuse
Content
import { collect as collectSkills } from "./collectors/skills.js";

// Allow self-signed certs for Portainer/UniFi
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";

// --- Load Config ---
const configPath = new URL("./config.json", import.meta.url);
Confidence
99% confidence
Finding
NODE_TLS_REJECT_UNAUTHORIZED = "0"

VirusTotal

64/64 vendors flagged this skill as clean.

View on VirusTotal

Static analysis

Detected: suspicious.dangerous_exec, suspicious.insecure_tls_verification

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
collectors/devservers.js:5

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
collectors/email.js:6

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
collectors/services.js:6

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
collectors/skills.js:7

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
collectors/system.js:7

HTTPS certificate verification is disabled.

Warn
Code
suspicious.insecure_tls_verification
Location
server.js:13