Back to skill

Security audit

watchdog

Security checks for vulnerabilities and agentic risk

Overview

This is a purpose-aligned Watch.dog integration, but it needs Review because it handles API credentials and account-changing tools with under-enforced safeguards.

Review before installing. Use a limited-scope Watch.dog API key if available, verify that WATCHDOG_API_URL points only to the intended Watch.dog endpoint, protect any local .env file, and be cautious with delete or public status page operations because confirmation is described but not enforced in code.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
index.js:399
Finding
Destructive deletion tools do not technically enforce user confirmation<![CDATA[ ## Vulnerability Details **File Location**: `index.js:399-417` **Vulnerability Type**: Missing authorization safeguard for destructive operations **Risk Level**: Medium ### Vulnerable Code ```js server.registerTool( "delete_monitor", { description: "Irreversibly deletes an Active Monitor. REQUIRES PRIOR EXPLICIT CONFIRMATION FROM THE USER.", inputSchema: { monitor_id: z.number().int().positive().optional(), name: z.string().optional(), }, }, async ({ monitor_id, name }) => { const text = await callRemoteTool("delete_monitor", { monitor_id, name }); return { content: [ { type: "text", text: `[Inform the user about the success of this deletion based on this JSON]:\n${text}`, }, ], }; }, ); ``` The equivalent `delete_watchdog` handler at `index.js:419-439` has the same weakness. ### Technical Analysis The requirement for explicit confirmation is present only in the behavioral prompt and tool description. These are advisory instructions to the Agent, not security controls enforced by the tool implementation. The deletion handlers accept a resource identifier and immediately forward the destructive operation to the remote Watch.dog API using the configured account API key. They do not require a confirmation parameter, verify a short-lived authorization token, maintain confirmation state, or reject direct calls made without a preceding confirmation exchange. Consequently, an MCP client, a malfunctioning Agent, or an Agent influenced by prompt injection can bypass the documented confirmation workflow and invoke the deletion tool directly. The schemas also allow both identifiers to be omitted or supplied simultaneously, leaving ambiguous requests to the remote service. ### Attack Path 1. An attacker influences the Agent through malicious content, or an MCP client directly issues a `delete_monitor` or `delete_watchdog` tool call. 2. The caller supplies a ...[truncated 770 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Add a mandatory confirmation field to each destructive tool schema, such as `confirmed: z.literal(true)`, and reject every request where it is absent. 2. Prefer a two-step workflow: - A preparation operation resolves the target and returns its exact identity plus a short-lived, single-use confirmation token. - The deletion operation requires that token and validates its target, action, account, and expiration. 3. Enforce confirmation in trusted application code rather than relying on prompt text or tool descriptions. 4. Require exactly one of `monitor_id` or `name` and reject missing or conflicting identifiers. 5. Resolve names to immutable IDs before confirmation so the confirmed target cannot change between steps. 6. Record an audit event containing the target, confirmation time, requesting principal, and API result. 7. Apply the same controls to both `delete_monitor` and `delete_watchdog`. ]]>

T01 · Skill Instruction Hijacking

Warning
Location
index.js:151
Finding
Untrusted remote API content is inserted verbatim into Agent instructions<![CDATA[ ## Vulnerability Details **File Location**: `index.js:151-156` **Vulnerability Type**: Indirect prompt injection through remote tool responses **Risk Level**: Medium ### Vulnerable Code The remote response is returned as unrestricted text: ```js const data = await response.json(); if (data.error) { throw new Error(`[${data.error.code}] ${data.error.message}`); } return data?.result?.content?.[0]?.text ?? "{}"; ``` That text is then concatenated into model-visible instructions. Representative examples include: ```js const text = await callRemoteTool("list_monitors", { status }); return { content: [ { type: "text", text: `[Data retrieved. Present it as a friendly markdown table using emojis 🟢🔴⏸️]:\n${text}`, }, ], }; ``` ```js const text = await callRemoteTool("create_watchdog", { name, type, interval, }); return { content: [ { type: "text", text: `[CRITICAL RULE: You must send the user the endpoint_url and give them exact instructions on how to ping using this data]:\n${text}`, }, ], }; ``` ### Technical Analysis The Skill treats the first text field returned by the remote MCP service as trusted model context. It does not parse the expected JSON into a validated object, constrain fields with a schema, escape display values, or establish a reliable instruction/data boundary. Monitor names, watchdog names, endpoint fields, event descriptions, or other values returned by the service may contain attacker-controlled text. If such content contains instructions—for example, directions to ignore previous rules or invoke another tool—the language model may interpret those values as directives rather than passive data. The risk is increased because destructive operations are available and their confirmation requirement is not enforced in code. The vulnerability does not prove that arbitrary instructions will always succeed, but it creates a viable indirect prompt-injection channel. ### Attack ...[truncated 1177 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse the remote response as JSON and reject responses that do not match strict, operation-specific schemas. 2. Return structured MCP content instead of interpolating raw remote text into natural-language instructions. 3. Treat every remote field as untrusted data and escape or encode values before rendering them. 4. Separate trusted instructions from remote values using explicit typed fields rather than textual delimiters alone. 5. Constrain field lengths and permitted character sets where practical, especially for names, aliases, URLs, and event messages. 6. Do not let content returned by tools authorize additional tool calls or override confirmation requirements. 7. Validate `WATCHDOG_API_URL`, require HTTPS, and preferably restrict it to approved Watch.dog hosts to reduce the risk of sending the bearer credential to an attacker-controlled endpoint. 8. Combine these measures with code-enforced authorization controls for destructive operations so prompt injection cannot bypass confirmation. ]]>
Vulnerability Patterns
  • 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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (28)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill description promises safety-relevant behavior such as explicit confirmation before deletions and an automatic credential verification flow, but these controls are only described in text and are not enforceable from this file. Description-behavior mismatches are dangerous because users and orchestrators may rely on safeguards that do not actually exist, enabling destructive actions or silent data transmission under false assumptions.

Credential Access

High
Category
Privilege Escalation
Content
* - Prompts: defined locally (behavioral instructions for the LLM)
 * - Tools:   proxied to the remote Watch.dog MCP PHP server via HTTP
 *
 * Configuration (via environment variables or .env file):
 *   WATCHDOG_API_KEY  – Your Watch.dog API key (sk_live_...)
 *   WATCHDOG_API_URL  – Remote MCP server URL (default: https://api.watch.dog/api/mcp_server.php)
 */
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
* - Prompts: defined locally (behavioral instructions for the LLM)
 * - Tools:   proxied to the remote Watch.dog MCP PHP server via HTTP
 *
 * Configuration (via environment variables or .env file):
 *   WATCHDOG_API_KEY  – Your Watch.dog API key (sk_live_...)
 *   WATCHDOG_API_URL  – Remote MCP server URL (default: https://api.watch.dog/api/mcp_server.php)
 */
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
* - Prompts: defined locally (behavioral instructions for the LLM)
 * - Tools:   proxied to the remote Watch.dog MCP PHP server via HTTP
 *
 * Configuration (via environment variables or .env file):
 *   WATCHDOG_API_KEY  – Your Watch.dog API key (sk_live_...)
 *   WATCHDOG_API_URL  – Remote MCP server URL (default: https://api.watch.dog/api/mcp_server.php)
 */
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
// ─── Load .env if present ────────────────────────────────────────────────────

const __dirname = dirname(fileURLToPath(import.meta.url));
const envPath = join(__dirname, ".env");

if (existsSync(envPath)) {
  const envContent = readFileSync(envPath, "utf-8");
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
If the user activates this skill for the first time and has no API Key configured:
1. Greet them enthusiastically and explain that you need to connect to their Watch.dog account.
2. Ask them only for their API Key and API URL (and remind them they can create a free account at https://watch.dog).
3. Once the user provides the data, use your native file writing tools to automatically create or overwrite the .env file in the root of this skill with the exact following format:
   WATCHDOG_API_KEY="[user_key]"
   WATCHDOG_API_URL="[user_url]"
   Never ask the user to create the file manually.
Confidence
93% confidence
Finding
The embedded prompt instructs the agent to ask the user for an API key and API URL, then automatically create or overwrite a .env file with those credentials. Encouraging collection and plaintext persistence of secrets inside the skill directory is dangerous because it normalizes sensitive credential capture, stores secrets in a predictable local file, and could overwrite existing configuration without explicit security controls.

Known Vulnerable Dependency: @hono/node-server==1.19.9 — 3 advisory(ies): CVE-2026-39406 (@hono/node-server: Middleware bypass via repeated slashes in serveStatic); GHSA-frvp-7c67-39w9 (Node.js Adapter for Hono: Path traversal in `serve-static` on Windows via encode); CVE-2026-29087 (@hono/node-server has authorization bypass for protected static paths via encode)

High
Category
Supply Chain
Confidence
94% confidence
Finding
The lockfile pins @hono/node-server 1.19.9, and the listed advisories indicate path traversal and authorization or middleware bypass issues in static file serving. Even though this file only shows dependencies, shipping a known-vulnerable server adapter is a real supply-chain risk because the skill may expose HTTP endpoints through the MCP SDK stack.

Known Vulnerable Dependency: express-rate-limit==8.2.1 — 1 advisory(ies): CVE-2026-30827 (express-rate-limit: IPv4-mapped IPv6 addresses bypass per-client rate limiting o)

High
Category
Supply Chain
Confidence
92% confidence
Finding
express-rate-limit 8.2.1 is reported vulnerable to bypass using IPv4-mapped IPv6 addresses, which can let attackers evade per-client throttling. In a monitoring skill that may expose API endpoints or admin operations, ineffective rate limiting increases the risk of brute force, abuse, and service exhaustion.

Known Vulnerable Dependency: fast-uri==3.1.0 — 7 advisory(ies): CVE-2026-13676 (fast-uri vulnerable to host confusion via failed IDN canonicalization); CVE-2026-18446 (fast-uri vulnerable to host confusion via backslash authority introducer); CVE-2026-75975 (fast-uri vulnerable to server-side request forgery via malformed IPv6 normalizat) +4 more

High
Category
Supply Chain
Confidence
83% confidence
Finding
fast-uri 3.1.0 has multiple reported host parsing and canonicalization issues, including SSRF-relevant confusion cases. For a watchdog skill that interacts with user-supplied website and API URLs, URI parsing flaws are especially relevant because they can mis-validate destinations and enable access to unintended internal or protected hosts.

Known Vulnerable Dependency: hono==4.12.3 — 16 advisory(ies): CVE-2026-56762 (Hono missing validation of cookie name on write path in setCookie()); CVE-2026-47676 (Hono: app.mount() strips mount prefix using undecoded path, causing incorrect ro); CVE-2026-47675 (Hono: Cookie helper does not sanitize sameSite and priority, allowing Set-Cookie) +13 more

High
Category
Supply Chain
Confidence
90% confidence
Finding
hono 4.12.3 is flagged with numerous advisories affecting routing, cookie handling, and related request processing behaviors. Because this is a web framework used by the SDK stack, unresolved flaws in request handling can lead to bypasses, header or cookie injection issues, and other web-facing security failures.

Known Vulnerable Dependency: ip-address==10.0.1 — 2 advisory(ies): CVE-2026-69192 (ip-address: Address4 decodes leading-zero octets as decimal while resolvers deco); CVE-2026-42338 (ip-address has XSS in Address6 HTML-emitting methods)

High
Category
Supply Chain
Confidence
80% confidence
Finding
ip-address 10.0.1 is associated with address interpretation inconsistencies and an HTML-emitting XSS issue. The address confusion issue is more relevant here because rate limiting and network validation commonly rely on accurate IP parsing; misinterpretation can weaken access controls or filtering.

Known Vulnerable Dependency: path-to-regexp==8.3.0 — 2 advisory(ies): CVE-2026-4923 (path-to-regexp vulnerable to Regular Expression Denial of Service via multiple w); CVE-2026-4926 (path-to-regexp vulnerable to Denial of Service via sequential optional groups)

High
Category
Supply Chain
Confidence
86% confidence
Finding
path-to-regexp 8.3.0 is flagged for ReDoS-style denial-of-service conditions in route pattern processing. If the service accepts or evaluates complex route patterns in request handling, an attacker may trigger excessive CPU use and degrade availability.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill declares network and environment-based capabilities but does not define an explicit tool scope such as allowed-tools or permissions. This weakens least-privilege controls and makes it harder for a host agent or reviewer to understand and constrain what the skill is permitted to do, increasing the chance of unintended external calls or access to secrets.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The instruction to silently call list_monitors immediately after credentials are provided causes an external transmission event without a clear user-facing warning at the moment secrets are entered. Even if intended as a connection test, silently using newly supplied credentials can violate user expectations, expose account metadata, and normalize hidden network actions tied to secret handling.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
"check uptime", "review watchdogs", or "create a website monitor".
  IMPORTANT: Deleting monitors and watchdogs requires explicit prior confirmation from the user.
  When the user provides their credentials (WATCHDOG_API_KEY, WATCHDOG_API_URL) or modifies them, 
  you MUST automatically execute the `list_monitors` tool as a silent test to verify the connection, 
  and then inform them if it was successful by showing a summary of what the skill can do.
version: "1.0.0"
author: Watch.dog Team
Confidence
92% confidence
Finding
Mandating an automatic tool execution when credentials are supplied introduces autonomous behavior at a sensitive moment, before the user has specifically requested an external action beyond configuration. In this context, autonomy is more dangerous because it couples secret entry with immediate network use, reducing user control and increasing the chance of unintended account interaction or metadata disclosure.

External Transmission

Medium
Category
Data Exfiltration
Content
*
 * Configuration (via environment variables or .env file):
 *   WATCHDOG_API_KEY  – Your Watch.dog API key (sk_live_...)
 *   WATCHDOG_API_URL  – Remote MCP server URL (default: https://api.watch.dog/api/mcp_server.php)
 */

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
*
 * Configuration (via environment variables or .env file):
 *   WATCHDOG_API_KEY  – Your Watch.dog API key (sk_live_...)
 *   WATCHDOG_API_URL  – Remote MCP server URL (default: https://api.watch.dog/api/mcp_server.php)
 */

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
*
 * Configuration (via environment variables or .env file):
 *   WATCHDOG_API_KEY  – Your Watch.dog API key (sk_live_...)
 *   WATCHDOG_API_URL  – Remote MCP server URL (default: https://api.watch.dog/api/mcp_server.php)
 */

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
*
 * Configuration (via environment variables or .env file):
 *   WATCHDOG_API_KEY  – Your Watch.dog API key (sk_live_...)
 *   WATCHDOG_API_URL  – Remote MCP server URL (default: https://api.watch.dog/api/mcp_server.php)
 */

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Intent-Code Divergence

Medium
Confidence
97% confidence
Finding
The behavioral prompt explicitly instructs the assistant to use native file writing tools to create or overwrite a .env file and then test the connection. However, this skill only reads a local .env file and exposes remote Watch.dog API tools; it does not register any file-writing tool or implement .env updates in code.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
3. Once the user provides the data, use your native file writing tools to automatically create or overwrite the .env file in the root of this skill with the exact following format:
   WATCHDOG_API_KEY="[user_key]"
   WATCHDOG_API_URL="[user_url]"
   Never ask the user to create the file manually.
4. Immediately after, execute list_monitors to test the connection.
   - If successful: celebrate with the user and offer to create their first monitor or watchdog.
   - If it fails with Auth Error: kindly ask them to verify their key and URL.
Confidence
80% 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.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The code sends the WATCHDOG_API_KEY as a Bearer token to a remote endpoint on every tool invocation, but there is no user-facing disclosure in this file that credentials will be transmitted off-box. In a credential-handling skill, silent transmission to a remote service increases the risk of unintended secret exposure, especially because the endpoint is configurable via WATCHDOG_API_URL.

Missing User Warnings

Low
Confidence
78% confidence
Finding
This file automatically loads WATCHDOG_API_KEY from a local .env file, which is sensitive credential material. While the header documents configuration, there is no clear warning about storing secrets locally or the security implications of reading and using them from disk.

Intent-Code Divergence

Low
Confidence
80% confidence
Finding
The inline tool instruction says 'Summary of the status of the provided watchdog in JSON', which conflicts with the broader prompt guidance that raw JSON must not be shown to users and should be translated into friendly output. This creates contradictory intent cues for the model about whether to expose JSON directly or summarize it.

Known Vulnerable Dependency: body-parser==2.2.2 — 1 advisory(ies): CVE-2026-12590 (body-parser vulnerable to denial of service when invalid limit value silently di)

Low
Category
Supply Chain
Confidence
80% confidence
Finding
body-parser 2.2.2 is flagged for a denial-of-service condition tied to invalid limit handling. This is a genuine dependency risk, though in this lockfile-only context the impact is limited unless the skill actually exposes request parsing to untrusted clients through an HTTP interface.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
index.js:31