T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/script.sh:336
- Finding
- Terminal Control-Sequence Injection Through Unsanitized Diagnostic Input<![CDATA[ ## Vulnerability Details **File Location**: `scripts/script.sh:336-345`, `scripts/script.sh:372`, and `scripts/script.sh:418` **Vulnerability Type**: Terminal control-sequence injection **Risk Level**: Medium ### Vulnerable Code At `scripts/script.sh:336-345`, attacker-controlled regular-expression captures are inserted into diagnostic suggestions without sanitization: ```python def format_fixes(fixes, match=None): result = [] for i, fix in enumerate(fixes, 1): f = fix if match: for j, g in enumerate(match.groups(), 1): f = f.replace(f"{{match{j}}}", g or "") result.append(f" {i}. {f}") return "\n".join(result) ``` At `scripts/script.sh:372`, an unrecognized input line containing an error-related keyword is printed directly: ```python print(f" Detected keyword: {CYAN}{line.strip()}{RESET}") ``` At `scripts/script.sh:418`, an unknown error code is printed directly: ```python print(f"\n{BOLD}📖 Error Code: {text}{RESET}") ``` ### Technical Analysis The script accepts untrusted error messages and logs through command-line arguments or standard input. These values, and substrings captured from them by regular expressions, are written directly to the terminal without escaping control characters. Terminal emulators interpret characters such as ESC, ANSI Control Sequence Introducer sequences, and Operating System Command sequences as instructions rather than visible text. An attacker who controls a log entry or error message can therefore embed terminal instructions in otherwise legitimate diagnostic data. Depending on the terminal and its configuration, a malicious sequence can: - Change colors or cursor position to conceal or overwrite diagnostic output. - Clear parts of the screen and forge apparently trustworthy messages. - Change the terminal title. - Create misleading hyperlinks. - Attempt clipboard modification through OSC 52 where that feature is enabled. The script's own ...[truncated 1808 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Sanitize every untrusted value before writing it to a terminal, including the original input, individual log lines, and regular-expression capture groups. 1. Introduce a centralized sanitizer that removes or visibly escapes terminal control characters: ```python def sanitize_terminal(value): # Preserve ordinary text while rendering control bytes harmless. return "".join( ch if ch in "\n\t" or ord(ch) >= 0x20 else f"\\x{ord(ch):02x}" for ch in value ) ``` 2. Apply the sanitizer before substituting captured groups: ```python safe_group = sanitize_terminal(g or "") f = f.replace(f"{{match{j}}}", safe_group) ``` 3. Sanitize direct output: ```python print(f" Detected keyword: {CYAN}{sanitize_terminal(line.strip())}{RESET}") print(f"\n{BOLD}📖 Error Code: {sanitize_terminal(text)}{RESET}") ``` 4. Consider replacing ESC (`0x1b`), C0/C1 controls, DEL, carriage returns, and other non-printable characters with explicit escaped representations. A production implementation should account for complete CSI and OSC sequence forms rather than relying only on a narrow regular expression. 5. Enable color output only when `sys.stdout.isatty()` is true, and provide a `--no-color` or safe plain-text mode. 6. Add regression tests using ANSI CSI sequences, OSC title changes, OSC 8 hyperlinks, OSC 52 clipboard sequences, carriage returns, backspaces, and mixed multiline input to verify that attacker-controlled bytes are displayed literally rather than interpreted. ]]>
