T09 · Insecure Skill Coding Practices
- Location
scripts/query.mjs:145- Finding
Terminal Escape-Sequence Injection Through Unsanitized Output
- Content
View full analysis
Vulnerability Details
File Location:
scripts/query.mjs:145-155, with terminal output sinks atscripts/query.mjs:177-178andscripts/query.mjs:193
Vulnerability Type: Terminal escape-sequence injection
Risk Level: MediumVulnerable Code
js if (data.data && data.data.length > 0) { data.data.forEach((item, index) => { const time = item.time || '未知时间'; const context = item.context || '无信息'; const location = item.location ? ` [${item.location}]` : ''; output += `${index + 1}. [${time}]${location} ${context}\n`; }); } else { output += `暂无物流信息,请稍后查询。\n`; }The tracking number is also emitted directly:
js console.log(`快递单号: ${trackingNumber}`); console.log(`快递公司: ${companyInfo.name}${companyInfo.code === 'unknown' ? ' (请使用 --company 指定)' : ''}\n`);The assembled output containing remote API values is subsequently printed:
js } else { console.log(output); }Technical Analysis
The script incorporates untrusted values into terminal output without validating or neutralizing terminal control characters. The affected inputs include:
- The tracking number supplied through the command line.
- The
time,context, andlocationfields returned by the external tracking services. - Other response-derived status text processed by the output formatter.
Terminal emulators interpret ANSI, CSI, and OSC escape sequences rather than displaying them as ordinary text. Consequently, a tracking number containing control sequences, or a malicious or compromised API response, can alter how the terminal renders the program's output.
This issue is terminal injection rather than shell command injection: the strings are not passed to a shell or command-execution API. The practical effects depend on the terminal emulator and its configuration.
Attack Path
- An attacker supplies a crafted tracking number containing terminal esc ...[truncated 1388 chars]
- Remediation
View remediation
Remediation Suggestions
- Validate tracking numbers against strict carrier-specific allowlists before making requests or displaying them. Reject control characters and unexpected punctuation rather than merely removing them.
- Sanitize every untrusted string received from command-line arguments or remote services before writing it to an interactive terminal.
- Remove C0 and C1 control characters, ANSI/CSI sequences, and OSC sequences. Prefer a maintained terminal-string sanitization library where dependencies are permitted.
- Apply sanitization independently to
trackingNumber,data.message,item.time,item.location, anditem.context. - Keep terminal-safe output separate from raw machine-readable data. If raw provider responses are needed, require an explicit option and write them using a structured format such as JSON.
- Add tests containing ESC, BEL, CSI, OSC 8 hyperlink, and OSC 52 clipboard sequences to verify that no control sequence reaches
console.log().
A defense-in-depth helper can reject or remove control characters before formatting:
js function sanitizeTerminal(value) { return String(value) .replace(/\x1B\][^\x07]*(?:\x07|\x1B\\)/g, '') .replace(/\x1B\[[0-?]*[ -/]*[@-~]/g, '') .replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F]/g, ''); }This should supplement, not replace, strict validation of tracking-number syntax.
