Back to skill

Security audit

File Watcher

Security checks for vulnerabilities and agentic risk

Overview

The skill itself is a coherent file-watching tool, but its install instructions tell users to download executable Python from a mutable GitHub branch without integrity verification.

Review the install path before using this skill. Prefer the bundled file_watcher.py or a pinned, verified release instead of the documented curl command from main, and avoid snapshotting broad or sensitive directories unless you are comfortable storing their metadata in JSON output.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Findings (1)

T03 · Remote Payload Retrieval and Execution

Warning
Location
SKILL.md:34
Finding

Mutable Remote Python Payload Downloaded for Later Execution

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:34 and mirrored installation guidance at README.md:36
Vulnerability Type: Unpinned remote payload retrieval
Risk Level: Medium

Vulnerable Code

SKILL.md:31-36:

bash
## Install

```bash
# Requires Python 3.8+. No pip install needed.
curl -O https://raw.githubusercontent.com/itsPremkumar/file-watcher/main/file_watcher.py
# Or copy the file anywhere — it's self-contained.

README.md:33-38 contains the same installation instruction:

bash
## Install

```bash
# Requires Python 3.8+. No pip install needed.
curl -O https://raw.githubusercontent.com/itsPremkumar/file-watcher/main/file_watcher.py
# Or copy the file anywhere — it's self-contained.

The downloaded file is subsequently executed by the documented quick-start commands, including:

bash
python file_watcher.py self-test
python file_watcher.py watch --help
python file_watcher.py once --help
python file_watcher.py diff --help

Technical Analysis

The installation instructions retrieve executable Python code from the mutable main branch of a personal GitHub repository. The URL is not pinned to an immutable commit, and the instructions provide no cryptographic checksum or signature verification.

Although curl does not execute the downloaded file directly, the documented workflow tells users to invoke it with Python. Consequently, the effective executable payload can change after this Skill package has been reviewed. A compromise of the upstream account or repository, or an unreviewed update to the branch, could cause users to download code that differs from the audited local file_watcher.py.

This remote download is not necessary for the declared filesystem-monitoring functionality because a self-contained copy of file_watcher.py is already included in the project. It therefore introduces avoidable network and software-supply-chain exposure beyond the minimum requirements of the Skill.

Attack Path

1 ...[truncated 1765 chars]

Remediation
View remediation

Remediation Suggestions

  1. Use the bundled implementation by default. Remove the remote download command and instruct users to invoke the packaged file_watcher.py directly.

  2. Pin remote downloads if they remain necessary. Reference an immutable, reviewed commit rather than main, for example:

    bash
    curl --fail --location \
      --output file_watcher.py \
      https://raw.githubusercontent.com/itsPremkumar/file-watcher/<FULL_COMMIT_SHA>/file_watcher.py
    
  3. Publish and verify an integrity digest before execution:

    bash
    printf '%s  %s\n' '<EXPECTED_SHA256>' 'file_watcher.py' | sha256sum --check -
    

    The expected digest should be distributed through a separately trusted, versioned release channel.

  4. Avoid silent replacement. Download to a temporary filename with restrictive creation semantics, verify it, and only then move it into place. Warn users before replacing an existing script.

  5. Use signed, versioned releases. Prefer authenticated release artifacts with signatures or attestations over raw branch content.

  6. Keep both documentation files consistent. Apply the remediation to SKILL.md:34 and README.md:36 so neither continues to recommend the unsafe workflow.

Vulnerability Patterns
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (5)

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
97% confidence
Finding

This function executes arbitrary Python files found in the target product directory as part of verification by invoking them with a self-test argument. In a CI or reviewer environment, an untrusted skill author can place malicious code in a .py file that ignores the argument and runs arbitrary commands, turning verification into code execution on the host.

Content

Scanner excerpt · ci/verify_product.py (reported line 37)May include surrounding context.

python
def has_self_test(fp):
    r = subprocess.run([sys.executable, fp, "self-test"], capture_output=True, text=True, timeout=30)
    return r.returncode == 0 and "PASS" in r.stdout

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · ci/verify_product.py (reported line 67)May include surrounding context.

python
all_ok &= axis(False, "frontmatter (no SKILL.md)")
        all_ok &= axis(False, "docs (no SKILL.md)")
    # 3 compiles
    comp_ok = all(subprocess.run([sys.executable, "-m", "py_compile", fp],
                                capture_output=True).returncode == 0 for fp in files)
    all_ok &= axis(comp_ok, "compiles (py_compile all .py)")
    # 4 self-test (any of 3 valid forms)

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
98% confidence
Finding

This code executes any test_*.py or *_test.py file present in the reviewed product directory. An attacker can submit a repository with a malicious test file so that CI or local verification runs arbitrary code under the verifier's privileges, making the 'verification' step an untrusted code execution primitive.

Content

Scanner excerpt · ci/verify_product.py (reported line 79)May include surrounding context.

python
tests = [os.path.join(folder, f) for f in os.listdir(folder)
                 if (f.startswith("test_") or f.endswith("_test.py")) and f.endswith(".py")]
        if tests:
            st_ok = all(subprocess.run([sys.executable, t], capture_output=True, text=True,
                                      timeout=30).returncode == 0 for t in tests)
            st_note = f"{len(tests)} test_*.py"
        elif re.search(r"(?im)^test\s*:", skill_txt):

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · ci/verify_product.py (reported line 92)May include surrounding context.

python
# 7 deploy-ready
    ci = os.path.join(os.path.dirname(os.path.abspath(__file__)), "ci_check.py")
    if os.path.isfile(ci) and os.path.isfile(skill):
        r = subprocess.run([sys.executable, ci], cwd=folder, capture_output=True, text=True)
        all_ok &= axis(r.returncode == 0, "deploy-ready (ci/ci_check.py PASS)")
    else:
        all_ok &= axis(True, "deploy-ready (skipped)")

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The once command can write a snapshot to disk that includes absolute path, file list, timestamps, sizes, and hashes for monitored files. Although the code prints that the snapshot was saved, it does not warn users that this output may expose filesystem structure or other sensitive metadata if stored or shared.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.