Back to skill

Security audit

agent-metrics-monitor

Security checks for vulnerabilities and agentic risk

Overview

This is a local metrics-monitoring library with some implementation caveats, but I found no hidden access, persistence, network activity, or destructive behavior.

Reasonable to install for local monitoring experiments or controlled inputs. Before using it in production, treat metric names and labels as trusted or pre-normalized, avoid high-cardinality values like request IDs or raw URLs, and document that the rate helpers are lifetime ratios rather than true rolling-window rates.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
index.js:495
Finding

Prometheus Exposition Format Injection Through Unvalidated Metric Metadata

Content
View full analysis
`${k}="${v}"`) .join(','); const labelStr = labels ? `{${labels}}` : ''; lines.push(`# TYPE ${this.prefix}_${counter.name} counter`); lines.push(`${this.prefix}_${counter.name}${labelStr} ${counter.get()}`); } // Export gauges for (const [key, gauge] of this.gauges) { const labels = Object.entries(gauge.labels) .map(([k, v]) => `${k}="${v}"`) .join(','); const labelStr = labels ? `{${labels}}` : ''; lines.push(`# TYPE ${this.prefix}_${gauge.name} gauge`); lines.push(`${this.prefix}_${gauge.name}${labelStr} ${gauge.get()}`); } ``` ### Technical Analysis The Prometheus exporter directly interpolates metric prefixes, metric names, label names, and label values into the text exposition format. It neither validates identifiers against Prometheus naming rules nor escapes special characters in label values. Prometheus label values require escaping of backslashes, double quotes, and newline characters. Metric and label names must also conform to the appropriate identifier syntax. Because the public collector APIs accept caller-provided names and labels, a value containing a quote and newline can terminate the current label value and introduce additional exposition lines. The same underlying issue affects histogram serialization at `index.js:521-528`, where names derived from caller-controlled keys and prefixes are directly inserted into output. ### Attack Path 1. An attacker gains influence over an operation name, metric name, label name, label value, or collector prefix passed to the library. 2. The attacker supplies crafted metadata containing exposition syntax, such as an embedded quote and newline. 3. The application records the ...[truncated 1091 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
index.js:341
Finding

Unbounded Metric Cardinality Can Exhaust Process Memory

Content
View full analysis
a.localeCompare(b)) .map(([k, v]) => `${k}=${v}`) .join(','); return labelStr ? `${name}{${labelStr}}` : name; } ``` ### Technical Analysis Every unique combination of metric name and labels creates a persistent entry in one of the collector's `Map` objects. There is no global series limit, per-metric cardinality limit, label-length limit, eviction policy, or rejection mechanism. The public recording methods accept caller-provided operation names and labels. Consequently, a high-cardinality value such as a request ID, timestamp, random token, user-controlled error type, or unique user identifier creates a new metric series on every call. The resource cost can be substantial because each unique histogram owns its own bucket array and may retain up to 10,000 observed values. Time-series storage also limits points per individual series bu ...[truncated 1498 chars]
Remediation
View remediation
Vulnerability Patterns
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • 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
Findings (4)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The getErrorRate and getSuccessRate methods accept a windowMs parameter but ignore it, returning lifetime ratios from monotonically increasing counters instead of a time-bounded rate. In a monitoring/alerting skill, this can suppress or delay detection of recent spikes in failures or recoveries, causing operators or automated systems to make unsafe decisions based on stale aggregate data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

This is a markdown file, so SQP-2 applies to documented behaviors that may affect user data or system integrity. The example instructs saving a generated dashboard with fs.writeFileSync, but the surrounding documentation does not warn that running the example will create or overwrite a local file.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The top-level documentation at L10-L12 lists 'Alert rule definitions for anomalies' and 'Anomaly detection' as features of the monitor. In practice, anomaly detection exists only as a standalone AnomalyDetector class at L716-L784 and is never connected to MetricsCollector, recordLatency, recordError, or evaluateAlerts, so the documented feature is not actually performed by the main monitoring flow.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.