Back to skill

Security audit

Skill Audit

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed skill-audit tool, but its own security checks can fail silently and may give users false confidence before enabling other skills.

Review this before relying on it in an install workflow. It does not show malicious behavior, but because it is itself a security gate with fail-open checks, do not use a PASS result as sufficient evidence that another skill is safe.

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

T09 · Insecure Skill Coding Practices

Error
Location
audit.sh:96
Finding

Malformed grep expressions cause security checks to fail open

Content
View full analysis
/dev/null; then print_fail "Possible OpenAI/API key detected" FOUND_CRITICAL=1 fi if grep -rqE "password\s*=\s*[\"']" . --include="*.md" --include="*.sh" --include="*.js" --include="*.json" 2>/dev/null; then print_fail "Possible hardcoded password detected" FOUND_CRITICAL=1 fi if grep -rqE "api_key\s*=\s*[\"']" . --include="*.md" --include="*.sh" --include="*.js" --include="*.json" 2>/dev/null; then print_fail "Possible hardcoded api_key detected" FOUND_CRITICAL=1 fi if grep -rqE "-----BEGIN.*PRIVATE KEY-----" . --include="*.md" --include="*.sh" 2>/dev/null; then print_fail "Private key found in skill files" FOUND_CRITICAL=1 fi if [[ $FOUND_CRITICAL -eq 0 ]]; then print_pass "No obvious hardcoded secrets found" fi if grep -rqE "http://(?!localhost|127\.0\.0\.1)" . --include="*.md" --include="*.sh" 2>/dev/null; then print_warn "Non-localhost HTTP URL found (consider HTTPS)" fi ``` ### Technical Analysis The private-key search passes a pattern beginning with hyphens directly to `grep`: ```bash grep -rqE "-----BEGIN.*PRIVATE KEY-----" . ``` Without `-e` or an option terminator before the pattern, `grep` may interpret the pattern as command-line options and terminate with an error instead of scanning the files. The external-URL expression uses negative lookahead: ```regex http://(?!localhost|127\.0\.0\.1) ``` The script selects extended regular expressions with `grep -E`, but POSIX extended regular expressions do not support Perl-style negative lookahead. The expression therefore produces an error rather than reliably identifying non-local HTTP URLs. ...[truncated 2259 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
audit.sh:137
Finding

Pipeline subshell discards missing-shebang warning severity

Content
View full analysis
/dev/null | while read -r f; do first=$(head -1 "$f" 2>/dev/null || true) if [[ ! "$first" =~ ^#! ]]; then MISSING_SHEBANG=1 print_warn "Shell script missing shebang: $f" fi done ``` ### Technical Analysis In Bash, each component of a pipeline normally executes in a subshell. The `while` loop is the final component of this pipeline: ```bash find ... | while read -r f; do ``` Consequently, assignments performed inside the loop—including the `SEVERITY=1` assignment made by `print_warn`—normally affect only the loop's subshell. When the loop terminates, the parent shell retains its previous `SEVERITY` value. The explicitly assigned `MISSING_SHEBANG=1` is lost for the same reason, and that variable is not checked after the loop. Thus, the script may display an individual warning while subsequently printing `All checks passed!` and returning exit status `0`, provided no independent check changed the parent shell's severity. This creates a mismatch between displayed findings, the final verdict, and the machine-readable process exit status. ### Attack Path 1. An attacker supplies a candidate skill containing one or more `.sh` files without a shebang. 2. The auditor runs `audit.sh` against the skill. 3. The `find` command supplies the file to the pipeline's `while` loop. 4. The loop calls `print_warn`, and the warning is displayed. 5. `print_warn` changes `SEVERITY` only in the pipeline subshell. 6. The loop exits, discarding the modified severity and `MISSING_SHEBANG` values. 7. If no other parent-shell check generated a warning or failure, the summary prints `All checks passed!`. 8. Automated installation logic sees exit code `0` and may enable the skill despite th ...[truncated 647 chars]
Remediation
View remediation
/dev/null || true) if [[ ! "$first" =~ ^#! ]]; then MISSING_SHEBANG=1 print_warn "Shell script missing shebang: $f" fi done < <(find . -name "*.sh" -type f -print0 2>/dev/null) ``` Using null-delimited paths also prevents filenames containing spaces or newlines from being split or misread. After the loop, enforce the result explicitly as defense in depth: ```bash if [[ $MISSING_SHEBANG -ne 0 && $SEVERITY -lt 1 ]]; then SEVERITY=1 fi ``` Additional hardening should include: 1. Add an automated test containing a shell file without a shebang. 2. Assert that the script emits a warning, prints a warning-level summary, and exits with status `1`. 3. Add filenames containing spaces and newlines to ensure path handling remains correct. 4. Consider avoiding mutable global severity state by recording findings in the parent process and calculating the final exit status from explicit counters. ]]>
Vulnerability Patterns
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • 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 (3)

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
70% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

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

md
### 2. Security Scan
- No hardcoded secrets, API keys, or credentials
- No suspicious external network calls (untrusted URLs)
- File permissions safe (no world-writable scripts)

### 3. Health Check
- Skill directory accessible

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
70% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · audit.sh (reported line 127)May include surrounding context.

sh
### 2. Security Scan
- No hardcoded secrets, API keys, or credentials
- No suspicious external network calls (untrusted URLs)
- File permissions safe (no world-writable scripts)

### 3. Health Check
- Skill directory accessible

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
70% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · audit.sh (reported line 125)May include surrounding context.

sh
fi

if find . -name "*.sh" -perm -002 2>/dev/null | grep -q .; then
  print_warn "World-writable shell scripts found (should be 755)"
else
  print_pass "No world-writable scripts"
fi

Static analysis

No suspicious patterns detected.