Back to skill

Security audit

System Monitor

Security checks for vulnerabilities and agentic risk

Overview

The skill is presented as a live server monitor, but the dashboard shows hardcoded and random health data instead of checking the configured service.

Review this before installing as a real monitor. It is suitable only as a visual mockup unless changed to fetch, authenticate, validate, and clearly display real health data; otherwise it can give false confidence that systems are healthy.

Vulnerability Patterns
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T07 · Tool Hijacking and Spoofing

Error
Location
monitor.html:406
Finding
Fabricated Health and Performance Telemetry Presented as Live Monitoring Data<![CDATA[ ## Vulnerability Details **File Location**: `monitor.html`, lines 251-274 and 406-439 **Related Documentation**: `SKILL.md`, lines 12-26 and 51-77 **Vulnerability Type**: Monitoring and API spoofing through fabricated telemetry **Risk Level**: High ### Vulnerable Code The interface initially presents the system as online and displays apparently valid gateway, activity, and response-time values: ```html <div class="card stat-card"> <div class="card-body"> <div class="stat-value cyan" id="systemStatus">ONLINE</div> <div class="stat-label">STATUS</div> </div> </div> <div class="card stat-card"> <div class="card-body"> <div class="stat-value green" id="gatewayStatus">98%</div> <div class="stat-label">GATEWAY</div> </div> </div> <div class="card stat-card"> <div class="card-body"> <div class="stat-value orange" id="lastActivity">12s</div> <div class="stat-label">LAST ACT</div> </div> </div> <div class="card stat-card"> <div class="card-body"> <div class="stat-value red" id="responseTime">45ms</div> <div class="stat-label">RESP TIME</div> </div> </div> ``` Although an API endpoint is declared, it is never queried. Instead, the displayed telemetry is generated randomly: ```javascript // CONFIG: Change this to your API endpoint const API_ENDPOINT = 'http://192.168.31.19:8000/healthz'; function initGraph() { const container = document.getElementById('performanceGraph'); const values = [65, 45, 78, 52, 88, 42, 71, 55, 83, 47, 76, 58]; container.innerHTML = values.map((v, i) => `<div class="graph-bar" style="height: ${v}px; animation-delay: ${i * 0.05}s"></div>` ).join(''); } function updateData() { const cpu = Math.floor(Math.random() * 40) + 30; const mem = Math.floor(Math.random() * 30) + 50; const net = Math.floor(Math.random() * 40) + 10; document.getElementById('cpuValue').textContent = cpu + '%'; d ...[truncated 3207 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace random telemetry generation with an authenticated request to the configured health endpoint: ```javascript async function updateData() { const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), 5000); try { const response = await fetch(API_ENDPOINT, { method: 'GET', headers: { 'Accept': 'application/json' }, signal: controller.signal, cache: 'no-store' }); if (!response.ok) { throw new Error(`Health endpoint returned ${response.status}`); } const data = await response.json(); // Validate data before updating the interface. } catch (error) { showUnavailableState(error); } finally { clearTimeout(timeout); } } ``` 2. Validate the response schema and types before using any returned fields. Reject missing, malformed, non-finite, or out-of-range values. 3. Default all operational fields to `UNKNOWN` rather than `ONLINE`. Change the display to `OFFLINE`, `UNREACHABLE`, or `INVALID RESPONSE` when the request fails, times out, or returns malformed data. 4. Derive system and gateway status exclusively from verified API data. Do not preserve a healthy status after communication has failed. 5. Remove random values, hard-coded service statuses, and sample activity records from production mode. If demonstration data is retained, label the entire interface prominently as `DEMO DATA — NOT LIVE`. 6. Display the timestamp of the last successful API response and mark data as stale after an appropriate interval. 7. Prefer a configurable same-origin HTTPS endpoint instead of the hard-coded plaintext private-network URL. This reduces mixed-content failures and avoids exposing health data to network interception. 8. If the health endpoint contains sensitive operational informatio ...[truncated 559 chars]
Vulnerability Patterns
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • 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
Findings (4)

Internal Network Request

Medium
Category
Server-Side Request Forgery
Content
Find and replace:
```javascript
const res = await fetch('http://192.168.31.19:8000/healthz');
```

Expected JSON response:
Confidence
70% confidence
Finding
Code issues a request to a loopback, link-local, or private-range host. This can reach internal services not meant to be exposed and is a common SSRF pivot.

Description-Behavior Mismatch

Medium
Confidence
98% confidence
Finding
The UI includes a button labeled 中文, suggesting language switching, but there is no toggleLang implementation anywhere in the script and the rest of the interface is only in English. This directly falls short of the claimed bilingual functionality.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The file embeds a private network API endpoint directly in client-side code, disclosing internal infrastructure details to any viewer of the page. In a monitoring skill context, that information can aid reconnaissance and may cause browsers running the page to attempt requests into an internal network, which is especially risky if later expanded to fetch real health data without proper access controls.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The manifest promises monitoring of server health, gateway connectivity, response times, and activity logs. In code, the displayed CPU, memory, network, last activity, and response time values are generated with Math.random(), while logs and service rows are hardcoded, so the page behaves as a demo dashboard rather than a real monitor.