T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/qa-check.sh:35
- Finding
- Terminal Control Sequence Injection Through Untrusted File Names and Content## Vulnerability Details **File Location**: `scripts/qa-check.sh:35-39, 55-57, 112-114, 134-136` **Vulnerability Type**: Terminal control sequence injection **Risk Level**: Medium ### Vulnerable Code ```bash if [ "$INPUT" = "-" ]; then CONTENT=$(cat) FILEPATH="(stdin)" else if [ ! -f "$INPUT" ]; then fail "File not found: $INPUT" exit 1 fi CONTENT=$(cat "$INPUT") FILEPATH="$INPUT" fi echo "═══════════════════════════════════════" echo "QA Gate $GATE Check: $FILEPATH" ``` Additional affected output sinks print matching attacker-controlled content without sanitization: ```bash if echo "$CONTENT" | grep -qiE '(TODO|PLACEHOLDER|TBD|Lorem ipsum)'; then fail "Placeholder text found" echo "$CONTENT" | grep -niE '(TODO|PLACEHOLDER|TBD|Lorem ipsum)' | head -5 ``` ```bash if echo "$CONTENT" | grep -qiE '(memory/|MEMORY\.md|AGENTS\.md|SOUL\.md|OpenClaw|heartbeat|sub-agent|cron job|sessions_spawn)'; then fail "Possible internal context leak detected" echo "$CONTENT" | grep -niE '(memory/|MEMORY\.md|AGENTS\.md|SOUL\.md|OpenClaw|heartbeat|sub-agent|cron job|sessions_spawn)' | head -5 ``` ```bash if echo "$CONTENT" | grep -qE '(console\.log|print\(.*debug|debugger;|pdb\.set_trace)'; then warn "Debug logging/breakpoints found" echo "$CONTENT" | grep -nE '(console\.log|print\(.*debug|debugger;|pdb\.set_trace)' | head -5 ``` ### Technical Analysis The script writes an untrusted file name and selected lines of untrusted file content directly to the operator's terminal. It does not remove or encode ASCII control characters, ANSI escape sequences, or Operating System Command sequences before output. Terminal emulators interpret these sequences as commands rather than ordinary text. Depending on terminal capabilities and configuration, crafted values may: - Clear or rewrite visible audit output. - Move the cursor and visually conceal reported findings. - Change ...[truncated 1898 chars]
- Remediation
- ## Remediation Suggestions 1. Sanitize every untrusted value before writing it to an interactive terminal. Remove C0/C1 control characters while retaining only intended line separators and printable characters. 2. Render file names in an escaped representation. Bash's `printf '%q'` is suitable for diagnostic shell output: ```bash printf 'QA Gate %q Check: %q\n' "$GATE" "$FILEPATH" ``` 3. Sanitize matching content before displaying it. For example, route it through a dedicated function that visibly encodes control bytes rather than emitting them: ```bash sanitize_terminal() { LC_ALL=C sed $'s/[\001-\010\013\014\016-\037\177]/?/g' } printf '%s\n' "$CONTENT" | grep -niE -- '(TODO|PLACEHOLDER|TBD|Lorem ipsum)' | head -5 | sanitize_terminal ``` 4. Use `printf '%s\n'` rather than `echo` for untrusted data. `echo` behavior can vary for values containing backslashes or option-like prefixes. 5. Add `--` before operands where supported so attacker-controlled values cannot be interpreted as command options. 6. Add regression tests containing ESC, OSC, carriage-return, backspace, and other control bytes in both file names and matching content. Verify that output displays escaped or replacement characters and cannot reposition the cursor or alter terminal state. 7. If machine-readable output is needed, provide a JSON or SARIF mode and serialize untrusted values with a standards-compliant encoder rather than relying on terminal formatting.
