Back to skill

Security audit

Workspace Analyzer

Security checks for vulnerabilities and agentic risk

Overview

This skill is a local workspace report generator, but its launcher uses an unsafe fixed temp output path and its read-only claims understate report-file writes.

Review before installing. The analyzer itself appears local and purpose-aligned, but prefer running the Python script directly with stdout or a private output path instead of run.sh, and treat its suggested file edits or git commits as manual changes that should be reviewed first.

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
run.sh:9
Finding

Predictable Temporary Report Enables Symlink-Based File Overwrite

Content
View full analysis

Vulnerability Details

File Location: run.sh:9 and scripts/analyzer.py:613-615
Vulnerability Type: Unsafe predictable temporary file handling
Risk Level: Medium

Vulnerable Code

run.sh:9:

bash
python3 "$SCRIPT_DIR/scripts/analyzer.py" --root "$WORKSPACE_ROOT" --output /tmp/workspace-analysis.json

scripts/analyzer.py:613-615:

python
if args.output:
    with open(args.output, 'w') as f:
        f.write(output_json)

Technical Analysis

The launcher always writes its report to the fixed, shared path /tmp/workspace-analysis.json. The analyzer then opens that path in write mode without checking whether it is a symbolic link, verifying ownership, or creating the file exclusively.

On Unix-like systems, open(path, 'w') follows symbolic links and truncates the resolved target. A local attacker who can create the predictable path before the victim invokes run.sh can replace it with a symbolic link to another file writable by the victim. The analyzer will subsequently truncate and replace that target with generated JSON.

Exploitation requires local access to the shared temporary directory and a target file that the process executing the skill is permitted to write.

Attack Path

  1. A local attacker predicts the fixed output path /tmp/workspace-analysis.json.
  2. Before the victim runs the skill, the attacker creates that path as a symbolic link to a file writable by the victim:
    bash
    ln -s /path/to/victim-writable-file /tmp/workspace-analysis.json
    
  3. The victim invokes run.sh.
  4. The launcher passes the attacker-controlled symbolic-link path to analyzer.py.
  5. open(args.output, 'w') follows the link and truncates the target.
  6. The analyzer overwrites the target with the generated JSON report.

Impact Assessment

The attacker can cause truncation and replacement of files writable by the account running the skill. Possible consequences include configuration corruption, loss of user data, a ...[truncated 255 chars]

Remediation
View remediation

Remediation Suggestions

  1. Create a unique report file with mktemp rather than using a fixed shared path:

    bash
    umask 077
    REPORT_FILE="$(mktemp "${TMPDIR:-/tmp}/workspace-analysis.XXXXXX.json")" || exit 1
    python3 "$SCRIPT_DIR/scripts/analyzer.py" \
      --root "$WORKSPACE_ROOT" \
      --output "$REPORT_FILE"
    
  2. Prefer a private runtime or cache directory owned by the invoking user instead of a globally shared directory.

  3. Harden file creation in Python by using exclusive creation when a new output is expected:

    python
    with open(args.output, "x", encoding="utf-8") as f:
        f.write(output_json)
    
  4. Where supported, use low-level file creation with O_CREAT | O_EXCL | O_NOFOLLOW and restrictive permissions such as 0600.

  5. If overwriting user-selected output files is required, use lstat to reject symbolic links and verify the destination's ownership and type before writing.

  6. Ensure all failure paths terminate safely and do not fall back to the predictable filename.

Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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
Findings (5)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
80% confidence
Finding

The skill documentation explicitly instructs agents to run a Python analyzer and also includes follow-on commands that write output files and perform git operations, but it declares no permissions or allowed-tools scope. That mismatch can cause an agent platform to grant broader-than-expected file access or leave reviewers unable to distinguish intended read-only analysis from write-capable behavior, increasing the chance of unintended workspace modification.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The top-level documentation explicitly claims 'read-only', which contradicts the later --output behavior that opens a file for writing and saves the JSON report. This is an active contradiction about side effects, not merely omitted detail.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest describes analyzing overall workspace structure and content to identify maintenance needs, bloat, duplicates, and organization issues. In practice, the scan is limited to *.md files via rglob("*.md"), so code, configs, binaries, and other workspace artifacts are excluded, making the actual behavior narrower than the stated purpose.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
75% confidence
Finding

The manifest emphasizes analysis and reporting for review, which is naturally satisfied by stdout or returned JSON. Allowing arbitrary file writes via --output adds a filesystem modification capability beyond the core need of workspace analysis.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

This code performs a file write to the path provided by --output. Although the CLI argument name suggests output behavior, the safety-disclosure criteria for code files call for some visible confirmation, logging, or explanatory comment/docstring at the operation site, and this write occurs without prior disclosure beyond the generic argument help.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.