Back to skill

Security audit

session-closeout

Security checks for vulnerabilities and agentic risk

Overview

This skill is a clearly disclosed, read-only closeout audit that reports workspace status without installing persistence or modifying files.

Install this if you want a manual, read-only session closeout check. Treat its printed report as advisory, and be cautious when running it in workspaces with untrusted or oddly named directories because path names are printed without structured escaping.

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

Warning
Location
scripts/session-closeout.sh:54
Finding
Unsanitized Repository Paths Enable Structured-Output and Terminal Injection## Vulnerability Details **File Location**: `scripts/session-closeout.sh`, lines 54–56 and 134–135 **Vulnerability Type**: Unsanitized output generated from attacker-controlled filenames **Risk Level**: Medium ### Vulnerable Code ```bash GIT_DIRS=() while IFS= read -r d; do GIT_DIRS+=("$d"); done < <( find "$ROOT" -maxdepth 4 -type d -name .git 2>/dev/null | sed 's#/\.git$##' | sort ) ``` ```bash if ((${#DIRTY[@]} > 0)); then echo "DIRTY_REPOS:" for d in "${DIRTY[@]}"; do echo "- $(rel_path "$d")"; done fi ``` ### Technical Analysis Repository paths are derived from directory names in the audited workspace, which may be controlled by an attacker. Unix filenames can contain newlines, carriage returns, tabs, and terminal escape characters. Shell quoting prevents these paths from being interpreted as shell commands, so this is not command injection. However, the script emits each path without encoding or filtering it, despite presenting its output as a line-oriented report containing `key=value` records. A crafted repository directory name can consequently: - Inject additional lines that resemble trusted report fields. - Inject false exception or status information. - Alter terminal rendering through ANSI escape sequences. - Cause downstream parsers to misinterpret report boundaries. The newline-delimited discovery pipeline is also unable to represent filenames containing newlines reliably. Such names may be split into multiple array entries before report generation. ### Attack Path 1. An attacker creates or supplies a workspace containing a dirty Git repository within the script's four-level search depth. 2. The repository's parent directory is assigned a crafted name containing a newline, carriage return, or ANSI terminal escape sequence. 3. The script discovers the `.git` directory and processes its path through the newline-delimited `find`, `sed`, and `sort` pipeline. 4. If `git status --porcelain` reports changes, the corresponding repository ...[truncated 724 chars]
Remediation
## Remediation Suggestions Use an unambiguous serialization format for all workspace-derived values: 1. Replace newline-delimited path discovery with NUL-delimited processing, such as `find ... -print0`, a NUL-aware sorting mechanism, and `read -r -d ''`. 2. Encode repository paths before including them in structured output. Suitable options include: - JSON string encoding. - Percent encoding. - Base64 with an explicitly documented field format. 3. If human-readable output is required, escape all control characters, including newlines, carriage returns, tabs, and bytes in the terminal escape range. 4. Avoid mixing machine-readable `key=value` output with unescaped free-form records. Prefer one JSON object containing arrays of encoded paths. 5. Document the selected encoding and require consumers to decode fields rather than treating raw lines as trusted records. 6. Add regression tests using repository names containing newlines, carriage returns, tabs, leading field-like text, and ANSI escape sequences.
Vulnerability Patterns
  • 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
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep

Static analysis

No suspicious patterns detected.