Back to skill

Security audit

Phy Pipeline Contract Enforcer

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly performs local data-contract checks, but one documented command handles filenames unsafely enough that a malicious filename could make the agent run unintended Python code.

Review before installing. Use this only on trusted local pipeline files or rewrite the CSV helper so file paths are passed as arguments rather than embedded into Python source. Avoid letting an agent run the provided shell snippets on attacker-supplied filenames unless it is sandboxed.

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

Error
Location
SKILL.md:150
Finding

Unsanitized Filename Interpolation Enables Python Code Injection

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 150–154
Vulnerability Type: Python code injection through unsafe shell-variable interpolation
Risk Level: High

Vulnerable Code

bash
# Get column names, types, null counts, sample values
python3 -c "
import csv, sys
from collections import defaultdict, Counter

with open('$FILE') as f:

Technical Analysis

The command directly interpolates the shell variable $FILE into a Python string literal embedded in a python3 -c program. Shell quoting does not safely encode the value for the resulting Python source code.

If an attacker can influence the input filename, a value containing a single quote and valid Python syntax can terminate the argument to open(), inject additional statements, and comment out the remaining source as needed. The injected statements would execute under the privileges of the user or agent running the documented command.

This is an exploitable coding pattern even though the project only contains documentation: the Skill explicitly directs an agent to execute the shown command while processing user-selected pipeline artifacts.

Attack Path

  1. An attacker supplies a CSV artifact with a specially crafted path or convinces the operator or agent to process such a path.
  2. The path is assigned to the $FILE shell variable.
  3. The agent follows the schema-extraction command in SKILL.md.
  4. The shell expands $FILE directly inside the source passed to python3 -c.
  5. Crafted quote characters terminate the intended Python string, allowing attacker-provided Python statements to become executable source.
  6. Python executes the injected statements with the current process privileges.

Exploitation depends on attacker control over the value placed in $FILE and execution of the documented command.

Impact Assessment

Successful exploitation permits arbitrary Python code execution with the privileges of ...[truncated 390 chars]

Remediation
View remediation

Remediation Suggestions

Do not interpolate filenames into dynamically generated Python source. Pass the path as a positional argument and read it from sys.argv:

bash
python3 - "$FILE" <<'PY'
import csv
import sys
from collections import Counter, defaultdict

file_path = sys.argv[1]
with open(file_path, newline="", encoding="utf-8") as f:
    reader = csv.DictReader(f)
    rows = list(reader)

schema = defaultdict(
    lambda: {"types": Counter(), "null_count": 0, "examples": []}
)

for row in rows:
    for col, val in row.items():
        schema[col]["null_count"] += 1 if not val.strip() else 0
        schema[col]["types"][type(val).__name__] += 1
        if len(schema[col]["examples"]) < 3:
            schema[col]["examples"].append(val)

for col, info in schema.items():
    null_pct = round(100 * info["null_count"] / len(rows), 1)
    print(
        f"{col}: {dict(info['types'])} | "
        f"null={null_pct}% | examples={info['examples']}"
    )
PY

Additional hardening measures:

  1. Move the validation implementation into a dedicated, reviewed Python script instead of constructing code through python3 -c.
  2. Parse paths through a structured argument parser and treat them strictly as data.
  3. Use -- where supported to separate options from path operands.
  4. Run analysis with least privilege and in a sandbox when processing attacker-controlled artifacts.
  5. Add regression tests covering filenames containing quotes, spaces, newlines, shell metacharacters, and leading hyphens.
Vulnerability Patterns
  • 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
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (1)

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The trigger phrases include broad, generic troubleshooting language such as schema-related breakage and downstream job failures, which can cause the skill to activate outside its intended scope. This increases the chance of unintended invocation on unrelated user inputs, potentially leading the agent to follow the skill’s local CLI/file-handling guidance in contexts where it is not appropriate.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.