Back to skill

Security audit

System Monitor

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent local system monitor, but it can expose process command lines and usernames while claiming its output contains no sensitive data.

Install only where users are allowed to see local process metadata. Avoid sending its reports to group chats or automated notifications unless process command lines are removed or made explicit opt-in, and do not run it with elevated privileges unless necessary.

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 (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/monitor.py:108
Finding
Incomplete Command-Line Redaction May Expose Process Secrets## Vulnerability Details **File Location**: `scripts/monitor.py`, lines 108–130 **Vulnerability Type**: Sensitive information exposure through incomplete redaction **Risk Level**: Medium ```python def sanitize_cmdline(cmdline: str) -> str: """Redact sensitive patterns from command lines.""" cmdline = re.sub(r'((?:token|key|secret|password|apikey|api_key|access_token)=)\S+', r'\1***', cmdline, flags=re.IGNORECASE) cmdline = re.sub(r'(--(?:token|key|password|secret|api-key))\s+\S+', r'\1 ***', cmdline, flags=re.IGNORECASE) return cmdline def get_top_processes(n=5): try: result = subprocess.run( ["ps", "aux", "--sort=-pcpu"], capture_output=True, text=True, timeout=5 ) procs = [] for line in result.stdout.strip().splitlines()[1:n+1]: parts = line.split(None, 10) if len(parts) >= 11: cmd = sanitize_cmdline(parts[10]) procs.append({ "user": parts[0], "pid": parts[1], "cpu": parts[2], "mem": parts[3], "rss_mb": round(int(parts[5]) / 1024, 1), "command": cmd[:60], }) return procs ``` ### Technical Analysis The monitor obtains system process information through `ps aux`, including usernames and complete command-line arguments. It then attempts to redact credentials using a denylist of selected parameter names. This redaction is incomplete because it only recognizes a limited set of exact patterns. Sensitive values can remain visible when supplied through: - Unrecognized options such as `--client-secret`, `--auth-token`, `--credential`, or `--private-key`. - Short options such as `-p secret`. - Positional command-line arguments. - Authorization headers or connection strings. - Database, HTTP, or other URLs containi ...[truncated 2186 chars]
Remediation
## Remediation Suggestions 1. Do not include complete process command lines in default output. Report only the executable or process name, such as the `comm` field. 2. Make command-line argument reporting an explicit opt-in feature with a clear warning that arguments can contain credentials and personal information. 3. Prefer allowlist-based output that exposes only known-safe process attributes instead of attempting to enumerate every possible sensitive parameter name. 4. If arguments must be displayed, redact or omit all argument values rather than relying solely on secret-name matching. 5. Consider using `ps` with a restricted output format, for example requesting PID, CPU, memory, and executable name without the full `args` field. 6. Apply data minimization to usernames and process identifiers when reports may be sent to group chats, logs, or external notification systems. 7. Add automated tests covering connection URLs, authorization headers, positional secrets, short options, alternative separators, and parameter-name variants. 8. Update `SKILL.md` to accurately warn that process metadata may be sensitive. Remove the unconditional claim that reports contain no tokens, paths, or user data unless this is technically enforced. 9. Run the monitor with the least-privileged account needed so operating-system process-visibility controls limit the available metadata.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (5)

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill advertises shell-based capabilities (`python3`, `ps`, `df`) but does not declare an explicit tool scope such as `permissions` or `allowed-tools`. In an agent environment, that ambiguity can let the runtime grant broader shell access than the skill actually needs, increasing the blast radius if the skill is misused or later modified.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger set includes generic phrases such as "monitor" and broad health-related wording that could cause accidental invocation outside the intended system-status context. Unintended invocation matters because this skill exposes host-level telemetry and process information, which may reveal operational details to users who did not explicitly ask for system inspection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def get_disk():
    try:
        result = subprocess.run(["df", "-h", "-x", "tmpfs", "-x", "devtmpfs"],
                                capture_output=True, text=True, timeout=5)
        disks = []
        for line in result.stdout.strip().splitlines()[1:]:
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
This skill enumerates top processes and exposes their command lines as part of routine monitoring output. In a system-monitoring context that makes the behavior functionally relevant, but it still creates an information disclosure risk because many programs place credentials, tokens, file paths, hostnames, and other sensitive operational details in argv; the existing sanitizer is incomplete and not a substitute for minimizing exposure.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def get_top_processes(n=5):
    try:
        result = subprocess.run(
            ["ps", "aux", "--sort=-pcpu"],
            capture_output=True, text=True, timeout=5
        )
Confidence
84% confidence
Finding
The code executes `ps` safely without a shell, so the subprocess call itself is not command injection. However, it collects process command lines and returns them to the caller, which can disclose sensitive information such as secrets passed as CLI arguments, internal paths, usernames, or service details; the current redaction only covers a few common patterns and is easy to bypass.

Static analysis

No suspicious patterns detected.