Back to skill

Security audit

Skill Preflight Checker

Security checks for vulnerabilities and agentic risk

Overview

This skill is meant to check other skills for safety, but some of its recommended commands could modify or delete local files while inspecting untrusted packages.

Review this skill carefully before installing. Its goal is reasonable, but do not let it run the documented npm or Docker checks in a real project directory as written. Use a fresh temporary directory, avoid writable host mounts, quote and validate package names, prefer npm inspection with lifecycle scripts disabled first, and require explicit user confirmation before any install, extraction, or cleanup command.

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

Error
Location
SKILL.md:93
Finding

Untrusted Package Installation Uses a Writable Host Bind Mount

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:93
Vulnerability Type: Unsafe container isolation and writable host-directory exposure
Risk Level: High

Vulnerable Code:

bash
# 在 Docker 中安装测试
docker run --rm -v $(pwd):/app node:alpine npm install package-name

Technical Analysis

The documented security-testing procedure installs an untrusted npm package inside a container while mounting the current host directory at /app with read-write access. npm packages can execute lifecycle scripts such as preinstall, install, and postinstall. Those scripts would execute inside the container but could read, create, overwrite, or delete files through the writable /app bind mount.

Consequently, the command does not provide the isolation claimed by the Skill. Container boundaries may protect unrelated host paths, but they do not protect the explicitly mounted directory. Code running as root inside the container may modify mounted files subject to the host filesystem and container-runtime mappings.

The $(pwd) expansion is also unquoted. Working-directory paths containing whitespace or command-option-like components can cause incorrect argument splitting and unpredictable command behavior.

The writable mount is not necessary for initial package inspection. A disposable volume or temporary directory would satisfy the declared testing purpose with substantially lower privileges.

Attack Path

  1. An attacker publishes an npm package containing a malicious lifecycle script.
  2. A user asks the Skill to perform a preflight safety check on that package.
  3. The agent follows the documented Docker command and mounts the current host project directory at /app with write access.
  4. npm install executes the attacker's lifecycle script inside the container.
  5. The script accesses /app and modifies or deletes files in the host working directory.
  6. The malicious changes persist on the host after t ...[truncated 772 chars]
Remediation
View remediation

Remediation Suggestions

  • Perform installation in a newly created disposable Docker volume rather than a host bind mount.

  • If host content is needed only for inspection, mount it read-only:

    bash
    docker run --rm \
      --mount type=bind,src="$PWD",dst=/input,readonly \
      --workdir /work \
      node:alpine \
      npm install --ignore-scripts package-name
    
  • Copy only the minimum required files into an isolated temporary location before testing.

  • Use npm install --ignore-scripts during static inspection. Run lifecycle scripts only in a second-stage sandbox with no host mounts, restricted networking, resource limits, dropped Linux capabilities, and a non-root user.

  • Quote all path expansions, including "$PWD".

  • Record filesystem changes inside a disposable container or volume rather than exposing the host project.

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:193
Finding

Unsafe Wildcard Extraction and Destructive Cleanup in Preflight Script

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:193-198
Vulnerability Type: Unsafe archive handling, uncontrolled wildcard operations, and destructive cleanup
Risk Level: Medium

Vulnerable Code:

bash
# 3. Download and scan
echo "3. Scanning for red flags..."
npm pack $SKILL_NAME
tar -xzf *.tgz
grep -r "curl\|wget\|eval" package/

# 4. Clean up
rm -rf package *.tgz

Technical Analysis

The script performs download, extraction, scanning, and cleanup directly in the current working directory rather than in a dedicated temporary directory.

tar -xzf *.tgz expands to every .tgz archive in the directory, including archives unrelated to the current scan. Likewise, rm -rf package *.tgz unconditionally removes any existing directory named package and every .tgz file in the working directory. The cleanup is not limited to artifacts created by npm pack.

The script also fails to capture and validate the exact archive filename returned by npm pack. Archive members are not inspected before extraction, and extraction is not constrained to a newly created private directory. These practices increase the risk of collisions, unintended overwrites, and unsafe handling of unexpected archive contents.

$SKILL_NAME is unquoted and unvalidated. Shell word splitting and pathname expansion can therefore change the arguments passed to npm. Input beginning with option syntax may also be interpreted as an npm command-line option rather than an intended package identifier.

Attack Path

  1. A user runs the documented preflight script from a populated project or download directory.
  2. That directory already contains a legitimate package/ directory or unrelated .tgz archives.
  3. The script downloads another package and expands *.tgz, causing all matching archives to be passed to the extraction command rather than only the newly downloaded artifact.
  4. Extraction can create or overwrite files ...[truncated 1366 chars]
Remediation
View remediation

Remediation Suggestions

  • Validate package identifiers against an explicit allowlist format and reject option-like or malformed input.
  • Quote the package value and use an option terminator where supported.
  • Create a private temporary directory and perform all operations inside it.
  • Capture the exact filename produced by npm pack instead of using *.tgz.
  • Inspect archive member names before extraction and reject absolute paths, traversal components, links to external locations, and unexpected entry types.
  • Extract only into the dedicated temporary directory.
  • Clean up only that exact temporary directory using a guarded exit trap.
  • Avoid running broad recursive deletion commands in the caller's working directory.

A hardened outline is:

bash
set -euo pipefail

SKILL_NAME=${1:?Package name required}

case "$SKILL_NAME" in
  -*|*[!A-Za-z0-9@._/-]*)
    echo "Invalid package identifier" >&2
    exit 1
    ;;
esac

workdir=$(mktemp -d)
trap 'rm -rf -- "$workdir"' EXIT

cd "$workdir"
archive=$(npm pack -- "$SKILL_NAME" | tail -n 1)

tar -tzf "$archive" > archive-members.txt
tar -xzf "$archive" -C "$workdir"
grep -rE 'curl|wget|eval' "$workdir/package" || true

Additional archive-member validation should be applied before the extraction command.

Vulnerability Patterns
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • 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 (9)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
78% confidence
Finding

The skill documentation is entirely in Chinese and presents the skill identity and usage only in that language, with no indication that users may choose another language or that the locale restriction is intentional and justified. This can be a natural-language policy issue if the organization requires avoiding forced language constraints without user opt-in.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The invocation examples are extremely generic phrases such as '检查这个技能', '预检 XXX 技能', and '安全分析', which can easily overlap with ordinary user requests. In an agent environment, overly broad triggers can cause accidental activation or routing to this skill when the user intended a normal conversation, potentially exposing skill behavior in unintended contexts or interfering with safer tool-selection logic.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

L003-L006 的自然语言描述整体固定为中文,未说明是否支持其他语言,也未给出用户选择语言的机制。根据规则,未经用户选择而强制单一语言属于语言/地区策略风险。

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

L043 的“帮我检查这个技能是否安全”是自然日常表达,缺少更明确的技能名、上下文范围或限定条件。文档也未提供负面示例或排除条件来说明何时不应激活该技能,因此存在触发范围过宽的风险。

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
75% confidence
Finding

Docker image references without a specific tag (:latest is implicit) or digest (@sha256:...) can be silently replaced by a malicious image.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
75% confidence
Finding

Docker image references without a specific tag (:latest is implicit) or digest (@sha256:...) can be silently replaced by a malicious image.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

L049 的“检查我准备安装的 5 个技能”没有限定技能来源、输入格式或必须处于安装前审查场景,容易与一般性的比较、评估或整理请求重叠。文档未说明哪些类似表述不应触发该技能。

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

Low
Category
Tool Misuse
Confidence
82% confidence
Finding

Mounting $(pwd) directly into a container that then runs npm install package-name exposes the host working directory to writes from untrusted package install scripts. Although the skill intends to test packages in isolation, this setup is not truly isolated: malicious preinstall/postinstall behavior inside the container can tamper with mounted files, poison the workspace, or modify checked-out code and artifacts.

Content

Scanner excerpt · SKILL.md (reported line 93)May include surrounding context.

Step 4:容器测试

bash
# 在 Docker 中安装测试
docker run --rm -v $(pwd):/app node:alpine npm install package-name

# 监控文件变化
docker run --rm -v $(pwd):/app node:alpine ls -la

Tool Parameter Abuse

Low
Category
Tool Misuse
Confidence
15% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · SKILL.md (reported line 96)May include surrounding context.

docker run --rm -v $(pwd):/app node:alpine npm install package-name

监控文件变化

docker run --rm -v $(pwd):/app node:alpine ls -la

text

---

Static analysis

No suspicious patterns detected.