Back to skill

Security audit

dep-audit

Security checks for vulnerabilities and agentic risk

Overview

This dependency-audit skill is mostly purpose-aligned, but it needs review because it recommends an unsafe remote installer and has under-disclosed file-writing and scanning behavior.

Install only if you are comfortable with local audit tools reading dependency metadata and, for Go/SBOM modes, traversing project contents. Do not run the suggested Syft `curl | sh` installer; install Syft through a trusted package manager or pinned verified release instead. Avoid running SBOM generation on untrusted directories until symlink-safe output handling is fixed.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (4)

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/detect.sh:87
Finding

Mutable Remote Installer Is Piped Directly into a Shell

Content
View full analysis

Vulnerability Details

File Location: scripts/detect.sh:83-87, scripts/sbom.sh:42-44, SPEC.md:42-48, and SPEC.md:153-156
Vulnerability Type: Unverified remote code retrieval and execution
Risk Level: Critical

Vulnerable Code

scripts/detect.sh:83-87:

bash
npm_info=$(tool_info "npm" "--version" "Pre-installed with Node")
pip_audit_info=$(tool_info "pip-audit" "--version" "pip install pip-audit")
cargo_audit_info=$(tool_info "cargo-audit" "--version" "cargo install cargo-audit")
govulncheck_info=$(tool_info "govulncheck" "-version" "go install golang.org/x/vuln/cmd/govulncheck@latest")
syft_info=$(tool_info "syft" "version" "curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh")

scripts/sbom.sh:42-44:

bash
if ! command -v syft >/dev/null 2>&1; then
  emit_error "syft not found. Install with: curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin" "$DIR"
  exit 1
fi

SPEC.md:42-48:

markdown
| Ecosystem | Lockfile(s) Detected | Audit CLI | JSON Flag | Install If Missing |
|-----------|---------------------|-----------|-----------|-------------------|
| **Node/npm** | `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml` | `npm audit` | `--json` | Pre-installed with Node |
| **Python** | `requirements.txt`, `Pipfile.lock`, `poetry.lock` | `pip-audit` | `--format json --output -` | `pip install pip-audit` |
| **Rust** | `Cargo.lock` | `cargo audit` | `--json` | `cargo install cargo-audit` |
| **Go** | `go.sum` | `govulncheck` | `-json` | `go install golang.org/x/vuln/cmd/govulncheck@latest` |
| **SBOM** | any of the above | `syft` | `-o cyclonedx-json` | `curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh \| sh` |

SPEC.md:153-156:

json
"pip-audit": { "available": true, "version": "2.7.3" },
"cargo-audit": { "available": false, "install": "carg
...[truncated 2647 chars]
Remediation
View remediation

Remediation Suggestions

  • Remove all curl | sh installation instructions from executable output and documentation.
  • Recommend an official operating-system package manager or another installation mechanism that supports package authenticity and version pinning.
  • If direct artifact installation is necessary:
    1. Require the user to select an explicit Syft version.
    2. Download a versioned release artifact rather than a mutable branch script.
    3. Download its publisher-provided checksum or signature separately.
    4. Verify the artifact before extraction or execution.
    5. Abort on any verification failure.
  • Prefer installation into a user-owned directory such as $HOME/.local/bin; do not default to /usr/local/bin.
  • Present installation steps for review and require explicit confirmation before downloading or installing software.
  • Keep installation separate from auditing and SBOM generation so the scan itself never becomes a software bootstrap channel.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/sbom.sh:38
Finding

SBOM Output Redirection Follows an Attacker-Controlled Symbolic Link

Content
View full analysis

Vulnerability Details

File Location: scripts/sbom.sh:38-55
Vulnerability Type: Symbolic-link file overwrite
Risk Level: High

Vulnerable Code

bash
OUTPUT="$DIR/sbom.cdx.json"

if ! command -v syft >/dev/null 2>&1; then
  emit_error "syft not found. Install with: curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin" "$DIR"
  exit 1
fi

if ! command -v jq >/dev/null 2>&1; then
  emit_error "jq not found — required for SBOM summary output" "$DIR"
  exit 1
fi

echo "Generating SBOM for $DIR ..." >&2

SBOM_RC=0
if run_timeout 60 syft "dir:$DIR" -o cyclonedx-json > "$OUTPUT" 2>/dev/null; then

Technical Analysis

The target directory is canonicalized with pwd -P, but the final output path is not validated. Shell output redirection follows an existing symbolic link at sbom.cdx.json. It also opens and truncates the linked target before syft runs.

Consequently, an untrusted project can include an output symlink that points outside the project. Requesting an SBOM then overwrites the symlink target with Syft output. Directory canonicalization does not prevent this because the symbolic link is the output file itself rather than the directory argument.

Attack Path

  1. An attacker supplies or modifies a project directory.
  2. The attacker creates sbom.cdx.json as a symbolic link to another file writable by the user, such as a shell configuration file or source file.
  3. The user asks the Skill to generate an SBOM for that project.
  4. The shell evaluates > "$OUTPUT" and follows the symbolic link.
  5. The destination is immediately truncated and then replaced with generated JSON, even if syft subsequently fails.

Impact Assessment

Exploitation allows destruction or replacement of any file writable by the Agent process. Under a normal user account, this may include project files, user configuration, shell sta ...[truncated 397 chars]

Remediation
View remediation

Remediation Suggestions

  • Reject a symbolic-link output before writing:

    bash
    if [ -L "$OUTPUT" ]; then
      emit_error "Refusing to write SBOM through a symbolic link" "$DIR"
      exit 1
    fi
    
  • Do not overwrite any existing output without explicit user confirmation.

  • Generate output into a securely created temporary file inside the resolved target directory.

  • Validate that the temporary file is a regular file owned by the current user.

  • Parse and validate the completed temporary SBOM before publishing it.

  • Atomically rename the temporary file to sbom.cdx.json only after successful generation.

  • Use restrictive creation permissions, such as umask 077, where the SBOM may contain sensitive internal dependency information.

  • Avoid running this Skill with elevated privileges.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/audit-pip.sh:51
Finding

Pipfile and Poetry Detection Audits the Ambient Python Environment Instead of the Target Lockfile

Content
View full analysis

Vulnerability Details

File Location: scripts/audit-pip.sh:51-66
Vulnerability Type: Scope violation and incorrect dependency-audit target
Risk Level: Medium

Vulnerable Code

bash
# Detect lockfile type and run pip-audit
RAW=""
AUDIT_RC=0
if [ -f "$DIR/requirements.txt" ]; then
  if RAW=$(run_timeout 30 pip-audit -r "$DIR/requirements.txt" --format json --output - 2>/dev/null); then
    AUDIT_RC=0
  else
    AUDIT_RC=$?
  fi
elif [ -f "$DIR/Pipfile.lock" ] || [ -f "$DIR/poetry.lock" ]; then
  if RAW=$(cd "$DIR" && run_timeout 30 pip-audit --format json --output - 2>/dev/null); then
    AUDIT_RC=0
  else
    AUDIT_RC=$?
  fi

Technical Analysis

The requirements.txt branch correctly passes a project-specific dependency file with -r. The Pipfile.lock and poetry.lock branch invokes bare pip-audit after changing directories but never supplies either detected lockfile.

A bare pip-audit invocation audits packages installed in the active Python environment. Changing the current working directory does not make it parse Pipfile.lock or poetry.lock. The generated report can therefore describe the Agent host's environment rather than the requested project.

This conflicts with the documented lockfile-oriented scope and can cause both false negatives and false positives. Dependencies present only in the target lockfile may be missed, while unrelated host packages may be disclosed or reported.

Attack Path

  1. A target project contains Pipfile.lock or poetry.lock, but no requirements.txt.
  2. Detection classifies the project as a supported Python target.
  3. audit-pip.sh enters the second branch and executes pip-audit without a dependency-file argument.
  4. pip-audit inventories the active Python environment instead of the target lockfile.
  5. Unrelated package names and versions affect the report and associated advisory lookups, while actual pro ...[truncated 663 chars]
Remediation
View remediation

Remediation Suggestions

  • Do not invoke bare pip-audit for Pipfile.lock or poetry.lock.
  • Use the corresponding trusted project tool to export locked dependencies into a securely created temporary requirements file, then run pip-audit -r against that file.
  • Ensure exports preserve exact locked versions and hashes where supported.
  • Keep temporary files private and remove them with an exit trap.
  • If a required exporter is unavailable, report the lockfile format as unsupported and skip it rather than auditing the ambient environment.
  • Include the exact input file and audit mode in normalized output so users can verify what was scanned.
  • Add tests that place different packages in the active environment and the target lockfile, then verify that only target dependencies appear in results.

other

Note
Location
SECURITY.md:5
Finding

Security Documentation Incorrectly Claims Project Source Is Never Accessed

Content
View full analysis

Vulnerability Details

File Location: SECURITY.md:5-19 and SECURITY.md:45-51; contradictory operations appear at scripts/audit-go.sh:57-60 and scripts/sbom.sh:53-55
Vulnerability Type: Misleading data-access and privacy boundary documentation
Risk Level: Low

Vulnerable Documentation and Code

SECURITY.md:5-19:

markdown
## What Data This Skill Touches

| Data | Access | Notes |
|------|--------|-------|
| Lockfiles (`package-lock.json`, `requirements.txt`, etc.) | **Read-only** | Parsed to identify packages and versions |
| Advisory databases (OSV, GitHub Advisory DB, RustSec) | **Read-only, network** | Fetched by upstream audit tools, not by this skill directly |
| SBOM output files | **Write** (only when explicitly requested) | Written to project directory as `sbom.cdx.json` |
| Project source code | **Never accessed** | Audit tools read lockfiles only, not source |

## Network Behavior

This skill does **not** make any network requests itself. The underlying audit tools (`npm audit`, `pip-audit`, `cargo audit`, `govulncheck`) each contact their respective advisory databases:

SECURITY.md:45-51:

markdown
## What This Skill Does NOT Do

- Does not scan container images or running services
- Does not detect zero-day vulnerabilities
- Does not phone home or send telemetry
- Does not modify any files without explicit user confirmation
- Does not execute project code (only reads lockfiles)
- Does not cache or store vulnerability data between runs

scripts/audit-go.sh:57-60:

bash
# govulncheck needs a Go project — run from the directory
RAW=""
AUDIT_RC=0
if RAW=$(cd "$DIR" && run_timeout 60 govulncheck -json ./... 2>/dev/null); then

scripts/sbom.sh:53-55:

bash
SBOM_RC=0
if run_timeout 60 syft "dir:$DIR" -o cyclonedx-json > "$OUTPUT" 2>/dev/null; then
  SBOM_RC=0

Technical Analysis

govulncheck -json ./... ...[truncated 1627 chars]

Remediation
View remediation

Remediation Suggestions

  • Replace the lockfile-only claim with an explicit per-mode access matrix.
  • State that:
    • npm, Python, and Cargo auditing primarily process dependency metadata.
    • Go reachability analysis traverses and analyzes Go packages under the target.
    • Directory-based Syft generation scans project contents and writes an SBOM.
  • Explain what dependency metadata each upstream tool may send to advisory services.
  • Require explicit confirmation before source-traversing Go analysis or directory-wide SBOM generation when handling untrusted or sensitive repositories.
  • Where practical, add a metadata-only mode that avoids source traversal and clearly distinguish its reduced accuracy.
  • Update SKILL.md, README.md, SECURITY.md, and SPEC.md consistently so permission claims match executable behavior.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (18)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared description says the skill audits dependencies for known vulnerabilities across several ecosystems. However, the supplied code chunk is only a detection script: it searches for lockfiles (npm/yarn/pnpm, Python, Rust, Go) and checks availability/version of tools like npm, pip-audit, cargo-audit, govulncheck, and syft. It outputs JSON describing the directory, discovered lockfiles, and installed tools. There is no code here that invokes those audit tools against the project, queries CVEs, parses vulnerability results, or supports remediation/fix confirmation. The behavior is therefore materially narrower and different from the declared primary purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared purpose is a dependency vulnerability auditor, but the supplied code only creates a software bill of materials (SBOM) using syft and summarizes the number of components. It does not query or analyze known vulnerabilities, does not produce CVE findings, and does not provide any remediation or confirmation workflow for fixes. While SBOM generation could be a supporting step in a security workflow, this chunk’s actual primary behavior is materially different from the declared vulnerability-audit functionality.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `aggregate.sh` now tolerates mixed inputs (valid results + error objects).

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

The combined rm -rf command removes multiple filesystem targets in one step, including a wildcard path, making accidental over-deletion harder for users to audit before execution. In the context of a report-only dependency auditing skill, destructive cleanup commands are not central to the skill's purpose and therefore stand out as unnecessary operational risk.

Content

Scanner excerpt · TESTING.md (reported line 169)May include surrounding context.

Cleanup

bash
rm -rf /tmp/dep-audit-test-* /tmp/npm-result.json /tmp/pip-result.json /tmp/dep-audit-error.json /tmp/unified.json /tmp/unified-mixed.json /tmp/report.md /tmp/report-mixed.md /tmp/dep-audit-empty

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
87% confidence
Finding

The combined rm -rf command removes multiple filesystem targets in one step, including a wildcard path, making accidental over-deletion harder for users to audit before execution. In the context of a report-only dependency auditing skill, destructive cleanup commands are not central to the skill's purpose and therefore stand out as unnecessary operational risk.

Content

Scanner excerpt · TESTING.md (reported line 169)May include surrounding context.

Cleanup

bash
rm -rf /tmp/dep-audit-test-* /tmp/npm-result.json /tmp/pip-result.json /tmp/dep-audit-error.json /tmp/unified.json /tmp/unified-mixed.json /tmp/report.md /tmp/report-mixed.md /tmp/dep-audit-empty

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

The combined rm -rf command removes multiple filesystem targets in one step, including a wildcard path, making accidental over-deletion harder for users to audit before execution. In the context of a report-only dependency auditing skill, destructive cleanup commands are not central to the skill's purpose and therefore stand out as unnecessary operational risk.

Content

Scanner excerpt · TESTING.md (reported line 169)May include surrounding context.

Cleanup

bash
rm -rf /tmp/dep-audit-test-* /tmp/npm-result.json /tmp/pip-result.json /tmp/dep-audit-error.json /tmp/unified.json /tmp/unified-mixed.json /tmp/report.md /tmp/report-mixed.md /tmp/dep-audit-empty

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · SECURITY.md (reported line 27)May include surrounding context.

md
| Abuse Case | Risk | Mitigation |
|------------|------|------------|
| User asks to "fix everything" → unreviewed package upgrades | **Medium** | Fix commands are never auto-executed. Agent must print commands and get explicit "yes" before running any. |
| Malicious lockfile tricks parser into code execution | **Low** | Scripts use `jq` for JSON parsing, not `eval`. No lockfile content is ever executed. |
| Scanning untrusted directories exposes file paths | **Low** | Paths appear only in the report shown to the user. No external transmission. |
| SBOM written to symlink-resolved path | **Low** | `sbom.sh` resolves symlinks via `cd && pwd`. A symlinked dir could cause writes to the target. Only runs when user explicitly requests SBOM generation. |

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.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The activation phrases are broad enough to trigger on generic security discussions, causing the skill to run shell-based discovery and potentially networked audit tooling in contexts where the user did not intend a dependency scan. In an agent ecosystem, overbroad auto-activation can expand the execution surface, surprise users, and leak repository structure or dependency metadata through tool invocations.

Content

No source excerpt is available for this finding.

File System Enumeration

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code scans file system directories looking for sensitive files. This could be reconnaissance for credential theft.

Content

Scanner excerpt · SPEC.md (reported line 32)May include surrounding context.

md
| Mode | Trigger | Behavior |
|------|---------|----------|
| **Single-dir audit** | "Audit this project" | Detect lockfiles in `.`, run audits, report |
| **Tree audit** | "Audit all projects in ~/code" | Walk directory tree, find lockfiles, audit each, aggregate |
| **SBOM generation** | "Generate an SBOM" | Run `syft` or `cdxgen`, output CycloneDX JSON |
| **Fix suggestions** | "Fix the critical vulnerabilities" | Print fix commands, **require explicit user confirmation** before executing any |

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger section says the skill activates when the user says generic terms like "audit", "vulnerability", "security scan", or asks to check dependencies/packages for issues. These phrases are broad enough to overlap with ordinary security discussions and do not clearly bound when the skill should activate versus when the agent should just answer conversationally.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The cleanup step includes a recursive force-delete command but provides no warning that it is destructive or that shell glob expansion can remove multiple filesystem entries. In a testing document, readers may copy/paste commands directly, so the lack of safety guidance increases the chance of accidental data loss if paths are modified or expanded unexpectedly.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest describes a skill for auditing dependencies for known vulnerabilities, but this script generates a CycloneDX SBOM file and reports component counts rather than performing vulnerability lookup or CVE analysis. Producing an SBOM may support later auditing, but as implemented here it performs inventory generation, which is materially broader/different than the stated report-only CVE audit behavior.

Content

No source excerpt is available for this finding.

External Script Fetching

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The spec recommends installing syft via curl ... | sh, which executes remote code directly from the network without integrity verification. If the upstream source, transport, or referenced script is compromised, the user could run arbitrary attacker-controlled shell commands on their system.

Content

Scanner excerpt · SPEC.md (reported line 48)May include surrounding context.

md
| **Python** | `requirements.txt`, `Pipfile.lock`, `poetry.lock` | `pip-audit` | `--format json --output -` | `pip install pip-audit` |
| **Rust** | `Cargo.lock` | `cargo audit` | `--json` | `cargo install cargo-audit` |
| **Go** | `go.sum` | `govulncheck` | `-json` | `go install golang.org/x/vuln/cmd/govulncheck@latest` |
| **SBOM** | any of the above | `syft` | `-o cyclonedx-json` | `curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh \| sh` |

**Docs:**
- npm audit: https://docs.npmjs.com/cli/commands/npm-audit

External Script Fetching

Low
Category
Supply Chain
Confidence
98% confidence
Finding

Embedding curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh as the suggested install command normalizes executing unverified remote scripts. This creates a supply-chain risk where compromise of the hosted script or repository branch could lead to full command execution under the user's privileges.

Content

Scanner excerpt · SPEC.md (reported line 156)May include surrounding context.

"pip-audit": { "available": true, "version": "2.7.3" }, "cargo-audit": { "available": false, "install": "cargo install cargo-audit" }, "govulncheck": { "available": false, "install": "go install golang.org/x/vuln/cmd/govulncheck@latest" }, "syft": { "available": false, "install": "curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh" } } }

text

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
72% confidence
Finding

The non-goals section states "Windows support — Linux/macOS only for MVP," which hard-limits platform/locale-style applicability in natural language. The file does not present this as a user choice or provide a stronger justification beyond implementation scope.

Content

No source excerpt is available for this finding.

External Script Fetching

Low
Category
Supply Chain
Confidence
15% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · scripts/detect.sh (reported line 87)May include surrounding context.

sh
OUTPUT="$DIR/sbom.cdx.json"

if ! command -v syft >/dev/null 2>&1; then
  emit_error "syft not found. Install with: curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin" "$DIR"
  exit 1
fi

External Script Fetching

Low
Category
Supply Chain
Confidence
15% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · scripts/sbom.sh (reported line 43)May include surrounding context.

sh
OUTPUT="$DIR/sbom.cdx.json"

if ! command -v syft >/dev/null 2>&1; then
  emit_error "syft not found. Install with: curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin" "$DIR"
  exit 1
fi

Static analysis

No suspicious patterns detected.