Back to skill

Security audit

Api Monitor Dashboard

Security checks for vulnerabilities and agentic risk

Overview

This API monitoring skill is mostly aligned with its stated purpose, but it has under-disclosed network exposure and unsafe input handling that users should review before installing.

Install only if you are comfortable reviewing and hardening the script first. Run it in a non-sensitive directory, do not monitor internal or metadata-service URLs, bind the dashboard to 127.0.0.1 or add authentication, and fix the jq URL handling before accepting untrusted endpoint values.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
monitor.sh:25
Finding
Arbitrary-Target Server-Side Request Forgery in Endpoint Monitoring<![CDATA[ ## Vulnerability Details **File Location**: `monitor.sh`, lines 25-34 and 88-95 **Vulnerability Type**: Server-Side Request Forgery (SSRF) **Risk Level**: High ### Vulnerable Code Endpoint values are passed directly to `fetch()`: ```javascript async function checkEndpoint(url) { const start = Date.now(); try { const res = await fetch(url); const time = Date.now() - start; return { url, status: res.status, time, ok: res.ok }; } catch (e) { return { url, status: 0, time: Date.now() - start, ok: false, error: e.message }; } } ``` The `add` action accepts an arbitrary URL without destination validation: ```bash add) URL="$2" if [ -z "$URL" ]; then echo "Usage: $0 add <url>" exit 1 fi echo "Adding $URL..." cat endpoints.json | jq ". += [\"$URL\"]" > tmp.json && mv tmp.json endpoints.json echo "✅ Added $URL" ;; ``` ### Technical Analysis The monitor treats every configured endpoint as trusted and issues an outbound request with Node.js `fetch()`. It does not restrict URL schemes, permitted hostnames, ports, resolved IP addresses, or redirects. Consequently, a user capable of adding an endpoint can direct the monitor toward loopback interfaces, private network ranges, link-local addresses, cloud metadata services, or other destinations reachable from the host. Redirects can also potentially bypass validation unless every redirect destination is independently checked. The generated dashboard does not expose response bodies, limiting direct data extraction. Nevertheless, response status, timing, success state, and error messages are recorded, enabling internal-network probing and blind interaction with HTTP services. GET endpoints that perform state changes could also be triggered. The script does not automatically execute `server.js`; exploitation requires the generated server to be started separately. ### Attack Path 1. Run `./monitor.sh start` to generate ...[truncated 1322 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Accept only explicitly supported schemes, preferably `https:`. - Maintain an explicit allowlist of approved monitoring hostnames or domains. - Resolve each hostname before connecting and reject loopback, private, link-local, multicast, unspecified, and reserved IP ranges for both IPv4 and IPv6. - Repeat destination validation after DNS resolution and before each request to mitigate DNS rebinding. - Disable redirects or validate the scheme, hostname, port, and resolved address of every redirect destination. - Restrict destination ports to those required by the monitoring use case. - Apply outbound firewall or proxy rules so the monitor cannot reach metadata services or sensitive internal networks. - Add request timeouts, response-size limits, and concurrency limits. - Do not return detailed internal connection errors to unauthenticated clients. - Require authorization before users can add or modify monitored endpoints. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
monitor.sh:88
Finding
jq Program Injection Through Unsafely Interpolated Endpoint URL<![CDATA[ ## Vulnerability Details **File Location**: `monitor.sh`, lines 88-95 **Vulnerability Type**: jq Expression Injection **Risk Level**: High ### Vulnerable Code ```bash add) URL="$2" if [ -z "$URL" ]; then echo "Usage: $0 add <url>" exit 1 fi echo "Adding $URL..." cat endpoints.json | jq ". += [\"$URL\"]" > tmp.json && mv tmp.json endpoints.json echo "✅ Added $URL" ;; ``` ### Technical Analysis The endpoint value is inserted directly into a double-quoted jq program: ```bash jq ". += [\"$URL\"]" ``` Shell quoting does not make the value safe for jq. Characters contained in `URL`, particularly double quotes and jq operators, can terminate the intended jq string and introduce additional jq expressions. This is expression injection rather than shell command injection: shell metacharacters produced by parameter expansion are not reparsed as shell syntax. However, the injected jq expression can still alter the generated JSON, read jq-accessible environment data through the `env` built-in, produce multiple JSON documents, or corrupt `endpoints.json`. For example, an input shaped like: ```text "], env # ``` causes the constructed jq source to resemble: ```jq . += [""], env #"] ``` This can make jq emit both the modified endpoint array and the process environment. Because jq can still exit successfully, the resulting `tmp.json` is moved to `endpoints.json`, potentially persisting environment values in a project file while also making the endpoint configuration invalid. ### Attack Path 1. Ensure `endpoints.json` exists, for example by first running `./monitor.sh start`. 2. Invoke the `add` action with a URL argument containing quote characters and jq syntax. 3. The script interpolates the argument into the jq source program. 4. jq executes the injected expression under the privileges and environment of the user running the script. 5. The injected expression emits attacker-selected data, transformed configur ...[truncated 1034 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Pass the URL as jq data rather than embedding it into jq source: ```bash jq --arg url "$URL" '. += [$url]' endpoints.json > tmp.json && mv tmp.json endpoints.json ``` Additional hardening should include: - Validate that the supplied value is a syntactically valid URL before saving it. - Validate that the existing JSON document is an array. - Reject control characters and enforce a reasonable maximum URL length. - Avoid the unnecessary `cat` pipeline. - Create the temporary file securely in the destination directory with `mktemp`. - Set restrictive permissions and remove the temporary file on failure or interruption. - Validate the completed file before atomically replacing `endpoints.json`. - Combine input handling with the SSRF destination controls described in the separate finding. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
monitor.sh:57
Finding
Unauthenticated Monitoring Dashboard Exposed on All Network Interfaces<![CDATA[ ## Vulnerability Details **File Location**: `monitor.sh`, lines 57-68 **Vulnerability Type**: Missing Authentication and Insecure Network Binding **Risk Level**: Medium ### Vulnerable Code ```javascript require('http').createServer((req, res) => { if (req.url === '/data') { res.writeHead(200, {'Content-Type': 'application/json'}); res.end(JSON.stringify(results.slice(-50))); } else { res.writeHead(200, {'Content-Type': 'text/html'}); res.end(html); } }).listen(3000); console.log('📊 Dashboard: http://localhost:3000'); ``` ### Technical Analysis The HTTP server calls `.listen(3000)` without specifying a hostname. Node.js therefore binds to an unspecified or wildcard address rather than explicitly limiting the service to `127.0.0.1`. This conflicts with the displayed `localhost` URL and can make the dashboard reachable from other network interfaces. Neither the dashboard nor the `/data` endpoint performs authentication or authorization. Any client able to connect to port 3000 can retrieve the recent monitoring results. The exposed records contain configured URLs, HTTP status codes, response times, success flags, and connection errors. These details can reveal internal service names, network topology, availability information, and operational failures. The `start` branch only generates `server.js` and does not launch it. Exposure begins if a user or another process subsequently runs the generated server. ### Attack Path 1. A user runs `./monitor.sh start`, generating `server.js`. 2. The generated application is launched with `node server.js`. 3. Node.js binds port 3000 without a loopback-only hostname. 4. A remote client with network reachability connects to the host on port 3000. 5. The client requests `/data` without credentials. 6. The server returns up to 50 recent endpoint results, including URLs and operational metadata. ### Impact Assessment A remote network client can obtain monitoring inform ...[truncated 497 chars]
Remediation
<![CDATA[ ## Remediation Suggestions For a local-only dashboard, bind explicitly to the loopback interface: ```javascript }).listen(3000, '127.0.0.1'); ``` If remote access is required: - Require authentication for the dashboard and `/data`. - Enforce authorization based on the minimum required access. - Place the service behind a TLS-enabled reverse proxy. - Restrict inbound access with host firewall and network security rules. - Avoid exposing detailed connection errors to clients. - Redact credentials, tokens, query parameters, and sensitive hostnames from displayed URLs. - Add security headers and return `404` for unknown routes rather than serving the dashboard for every path. - Clearly document the actual bind address and exposure model. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (5)

External Transmission

Medium
Category
Data Exfiltration
Content
./monitor.sh start

# Add endpoint
./monitor.sh add https://api.example.com/health

# Check status
./monitor.sh status
Confidence
50% 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
94% confidence
Finding
The file header says "API Monitor - Quick Start" and the start path prints "Starting API Monitor", implying a working monitor service. However, the script only writes out server.js and endpoints.json and never actually runs the Node server, while the status command reads data/*.json even though the generated Node code never writes any JSON files under data/. These comments/messages and operational labels actively misrepresent the behavior users would expect from the script.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
This shell script creates and overwrites local files such as server.js and endpoints.json, and later updates endpoints.json via jq. Although it prints progress messages, it does not clearly disclose that running the skill will create or replace files in the current working directory, which is a user-impacting filesystem operation.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The generated server performs automated fetches to user-supplied URLs from the local machine or host environment, creating an SSRF-like capability that can be used to probe internal services, cloud metadata endpoints, or other network-restricted resources. The danger is increased by the skill context because this behavior is packaged as a simple monitoring utility and lacks any validation, allowlisting, or explicit warning about outbound network access and privacy implications.

Missing User Warnings

Low
Confidence
83% confidence
Finding
This is a markdown file, so missing-warning checks apply to described behaviors that may affect privacy or system integrity. The feature list states that alerts are sent via email/Slack, but the document does not warn users that endpoint status and monitoring metadata may be transmitted to third-party services.

Static analysis

No suspicious patterns detected.