Back to skill

Security audit

Skill Lint

Security checks for vulnerabilities and agentic risk

Overview

The linter itself is mostly straightforward, but users are told to download and run mutable remote Python code, and a bundled verifier can execute Python files from supplied folders without isolation.

Review before installing. Prefer running the bundled audited skill_lint.py directly, or only download from an immutable commit with checksum verification. Do not run ci/verify_product.py on untrusted folders unless it is inside a disposable sandbox with no secrets or network access.

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 (2)

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:31
Finding

Unpinned Remote Python Payload Downloaded from a Mutable Branch

Content
View full analysis
Remediation
View remediation
/skill_lint.py echo " skill_lint.py" | sha256sum --check - python skill_lint.py self-test ``` 4. Prefer signed release artifacts and document signature verification. 5. Apply branch protection, mandatory review, least-privilege repository tokens, and multi-factor authentication. 6. Keep `README.md` and `SKILL.md` synchronized so neither reintroduces the mutable download path. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
ci/verify_product.py:41
Finding

Verification Harness Executes Python Code from Supplied Product Folders Without Isolation

Content
View full analysis
Remediation
View remediation
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 (4)

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
96% confidence
Finding

This function executes arbitrary Python files from the target product folder as part of verification by invoking python <file> self-test. In a CI or review context, an untrusted contributor can place malicious code in a .py file that performs harmful actions before or instead of handling the self-test argument, leading to arbitrary code execution on the verifier 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
97% confidence
Finding

This code executes any test_*.py or *_test.py file found in the target folder. Because those test files come from the untrusted product under review, an attacker can submit a malicious test file that exfiltrates secrets, alters the CI environment, or performs arbitrary commands when the verifier runs it.

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)")