Back to skill

Security audit

Local Healthcheck

Security checks for vulnerabilities and agentic risk

Overview

This is a small local health-check skill with disclosed reporting behavior, but users should notice that it runs several sudo-based inspection commands and writes host-security details to a predictable local file.

Install only if you are comfortable with a local script that may prompt for sudo and records firewall, port, update, and SSH status in a markdown file. Run it from a trusted directory, review check.sh first, and avoid running the entire script as root; the publisher should remove unnecessary sudo use and protect the report path and permissions.

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

T05 · Unauthorized Access and Privilege Escalation

Note
Location
check.sh:7
Finding
Unnecessary Privileged Host Reconnaissance<![CDATA[ ## Vulnerability Details **File Location**: `check.sh`, lines 7–29 **Vulnerability Type**: Excessive privilege use during local security checks **Risk Level**: Low ### Complete Code Snippet ```bash if command -v firewallctl >/dev/null 2>&1; then firewallctl status || echo "无法获取防火墙状态" elif [[ "$OSTYPE" == "darwin"* ]]; then /usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate || echo "防火墙状态未知" else sudo ufw status || echo "防火墙状态未知" fi echo "\n## 打开的端口" if [[ "$OSTYPE" == "darwin"* ]]; then sudo lsof -nP -iTCP -sTCP:LISTEN | awk 'NR>1 {print $9}' | sort | uniq else sudo ss -tuln fi echo "\n## 系统软件更新" if [[ "$OSTYPE" == "darwin"* ]]; then softwareupdate -l || echo "更新检查失败" else sudo apt list --upgradable 2>/dev/null || echo "更新检查失败" fi echo "\n## SSH 服务状态" if pgrep -x sshd >/dev/null; then echo "sshd 正在运行" else echo "sshd 未运行" fi ``` ### Technical Analysis The script performs read-only host reconnaissance, including firewall inspection, listening-port enumeration, package-update discovery, and SSH daemon detection. These operations are consistent with the documented health-check purpose, but several commands are invoked through `sudo` even though they commonly do not require elevated privileges, particularly: ```bash sudo ss -tuln sudo apt list --upgradable ``` Unnecessary use of `sudo` violates least-privilege principles and conditions users to approve elevation for routine inspection. The collected output also reveals the system's network exposure and patch state. The commands are fixed rather than attacker-controlled, so the code does not provide a direct command-injection path or arbitrary root-code execution. The concern is the unnecessarily broad privilege boundary and the collection of security-sensitive host metadata. ### Attack Path 1. A user invokes the local health-check skill. 2. The script reaches one or more commands prefixed with `sudo`. 3. The user m ...[truncated 1054 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `sudo` from commands that can run with ordinary user privileges: ```bash ufw status lsof -nP -iTCP -sTCP:LISTEN ss -tuln apt list --upgradable ``` 2. If a specific platform genuinely requires elevation, explain why and obtain explicit user consent before invoking `sudo`. 3. Prefer capability detection and graceful degradation over automatic privilege escalation. 4. Collect only the listener and update information required for the report. 5. Protect the generated report with restrictive permissions because it contains host-security metadata: ```bash umask 077 ``` ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
check.sh:3
Finding
Predictable Report File Permits Symlink-Based Overwrite and Information Exposure<![CDATA[ ## Vulnerability Details **File Location**: `check.sh`, lines 3–4 and 31 **Vulnerability Type**: Predictable output path, symbolic-link following, and unrestricted default permissions **Risk Level**: Medium ### Complete Code Snippet ```bash REPORT="$(date +%F)" OUT_FILE="$(pwd)/memory/healthcheck-${REPORT}.md" ``` ```bash } > "$OUT_FILE" ``` ### Technical Analysis The report path is deterministic because it consists of the current working directory, a fixed `memory` directory, and the current date. The script then opens that path with ordinary shell redirection: ```bash > "$OUT_FILE" ``` Shell redirection follows an existing symbolic link and truncates the linked target. The script does not verify that: - `memory` is a trusted directory; - the destination is a regular file; - the destination does not already exist; - the destination is not a symbolic link; or - the directory and report have restrictive permissions. Consequently, if another local user or process can write to the project’s `memory` directory, it can pre-create the expected filename as a symbolic link. When the skill runs, the invoking shell follows that link and truncates or replaces a file writable by the invoking user. The redirection itself is performed by the shell running the script, not by the individual `sudo` commands inside the redirected block. Therefore, this issue does not by itself permit overwriting root-only files unless the entire script is run with elevated privileges. The report also contains firewall, network-listener, update, and SSH-service information. Without a restrictive `umask`, the generated file may be readable by other local users depending on the environment's default permissions. ### Attack Path 1. An attacker obtains write access to the project’s `memory` directory. 2. The attacker predicts the filename using the current date: ```text memory/healthcheck-YYYY-MM-DD.md ``` 3. The attacker creates that path as a symbolic link to anothe ...[truncated 1063 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Set a restrictive process umask before creating the report: ```bash umask 077 ``` 2. Create the report directory with owner-only permissions: ```bash install -d -m 700 -- "$(pwd)/memory" ``` 3. Verify that the destination directory is trusted and is not a symbolic link. 4. Refuse to overwrite an existing destination, including a symbolic link. For example, enable exclusive creation with shell noclobber where appropriate: ```bash set -o noclobber ``` 5. Prefer creating a temporary file securely in the protected directory and atomically renaming it after successful report generation. 6. Confirm that the temporary and final paths are regular files owned by the invoking user. 7. Avoid running the complete script as root. Elevate only an individual command when strictly necessary so output-file redirection remains unprivileged. 8. Handle a missing `memory` directory explicitly rather than relying on it to exist. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • 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
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The skill’s declared scope is a simple local health check without external dependencies, but its documented behavior includes broader system enumeration and persistent file writes that are not clearly disclosed in the high-level description. This mismatch can mislead users about what the skill will access or modify, weakening informed consent and making unexpected privileged or state-changing actions more likely to be run.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
elif [[ "$OSTYPE" == "darwin"* ]]; then
    /usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate || echo "防火墙状态未知"
  else
    sudo ufw status || echo "防火墙状态未知"
  fi
  echo "\n## 打开的端口"
  if [[ "$OSTYPE" == "darwin"* ]]; then
Confidence
90% confidence
Finding
Using sudo for `ufw status` grants the script elevated execution capability for the firewall status check. While the command itself is read-oriented, requiring root privileges where not clearly disclosed increases the blast radius if the script is altered or if users over-trust similar skills.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
The script invokes multiple commands via sudo even though it is presented as a simple local health check. Prompting for elevated privileges broadens the trust boundary: if the script is modified, wrapped, or run in unsafe environments, it gains access beyond what users may reasonably expect from the description.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The script runs privileged checks without any in-script warning, dry-run mode, or confirmation step. Users may trigger sudo prompts and privileged execution unexpectedly, which is risky for a skill advertised as simple and dependency-free, especially because elevated execution can expose additional system information and normalize unsafe privilege escalation.

Description-Behavior Mismatch

Medium
Confidence
92% confidence
Finding
The skill description claims only firewall, updates, and SSH status checks, but the script also enumerates listening ports and persists the results to a markdown file under the current working directory. This expands data collection beyond the declared scope and creates a local artifact containing potentially sensitive network exposure information, which can surprise users and increase disclosure risk.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
fi
  echo "\n## 打开的端口"
  if [[ "$OSTYPE" == "darwin"* ]]; then
    sudo lsof -nP -iTCP -sTCP:LISTEN | awk 'NR>1 {print $9}' | sort | uniq
  else
    sudo ss -tuln
  fi
Confidence
92% confidence
Finding
Running `sudo lsof -nP -iTCP -sTCP:LISTEN` elevates privileges to enumerate listening ports in more detail than users may expect from the stated functionality. The resulting output can reveal sensitive local service exposure and normalizes privileged execution for a task that should be transparently disclosed.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
if [[ "$OSTYPE" == "darwin"* ]]; then
    sudo lsof -nP -iTCP -sTCP:LISTEN | awk 'NR>1 {print $9}' | sort | uniq
  else
    sudo ss -tuln
  fi
  echo "\n## 系统软件更新"
  if [[ "$OSTYPE" == "darwin"* ]]; then
Confidence
91% confidence
Finding
Executing `sudo ss -tuln` similarly requires elevated privileges for local port enumeration on non-macOS systems. Even if used for diagnostics, it expands capability beyond the advertised checks and contributes to unnecessary privilege escalation for routine health reporting.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
if [[ "$OSTYPE" == "darwin"* ]]; then
    softwareupdate -l || echo "更新检查失败"
  else
    sudo apt list --upgradable 2>/dev/null || echo "更新检查失败"
  fi
  echo "\n## SSH 服务状态"
  if pgrep -x sshd >/dev/null; then
Confidence
83% confidence
Finding
Using `sudo apt list --upgradable` for package update visibility may be unnecessary on many systems and conditions users to provide elevated privileges for a read-style check. Although lower impact than firewall or port inspection, it still broadens privileges beyond a minimal health check's expected scope.

Missing User Warnings

Low
Confidence
88% confidence
Finding
The skill explicitly writes a report into local storage but does not clearly warn users in the description that it modifies the filesystem. Even though the write is limited and plausibly expected for reporting, undisclosed persistence can still surprise users and may expose sensitive host information if the report is stored insecurely.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
All user-facing report headings and status messages are hardcoded in Chinese, with no option for the user to select language and no documented justification that the skill is region- or locale-specific. This creates a natural-language policy concern because the skill imposes a specific language without opt-in.

Static analysis

No suspicious patterns detected.