What landed in CVE-land this week
This week's disclosure feed reads like a time capsule. Seven of the eight new entries touch ncurses, the terminal-handling library that ships with essentially every Unix-like operating system, and half are resurfaced research from 2017. One — CVE-2000-0963 — is old enough to vote. Age doesn't make them irrelevant. The real story isn't that ncurses has bugs; it's that ncurses has a bug class that keeps returning because the library sits under so much tooling that nobody remembers it's a parser.
If you run containers, CI runners, SSH bastions, or embedded Linux fleets, at least one thing in your environment links libncurses and reads TERM, TERMINFO, or TERMINFO_DIRS from an attacker-influenced environment. That's what this digest is about.
The digest at a glance
| CVE | Component | Class | Trigger | |---|---|---|---| | CVE-2000-0963 | ncurses | Buffer overflow | Long TERM / TERMINFO_DIRS env vars | | CVE-2002-0062 | ncurses 5.0 (RH ncurses4 compat) | Buffer overflow | Cursor-move / scroll routines | | CVE-2017-10684 | ncurses 6.0 | Stack overflow in fmt_entry | Crafted terminfo | | CVE-2017-10685 | ncurses 6.0 | Format string in fmt_entry | Crafted terminfo | | CVE-2017-11112 | ncurses 6.0 | OOB access in append_acs | Untrusted terminfo | | CVE-2017-11113 | ncurses 6.0 | NULL deref in _nc_parse_entry | Untrusted terminfo | | CVE-2017-13728 | ncurses 6.0 (libtic) | Infinite loop in next_char | Crafted input | | CVE-2017-13729 | ncurses 6.0 | Illegal address in _nc_save_str | Crafted input |
The CVSS column is missing on purpose. NVD is publishing these entries with 0.0 scores — the CNA has not yet assigned vectors — and that gap is exactly what an ops team will use to justify closing the ticket. Do not close the ticket. Severity here is contextual, and the context is where the work is.
Why terminfo is a parser you forgot you had
ncurses isn't just a "draw boxes on a TTY" library. It reads compiled terminfo entries from disk, walks each entry through _nc_read_entry / _nc_parse_entry / fmt_entry / _nc_save_str, and interprets embedded escape sequences and capability strings. Every 2017 CVE above is a bug in that parser. The attack surface is: any process that links ncurses and can be pointed at a terminfo entry the attacker controls.
The environment-variable path is the classic one. TERMINFO and TERMINFO_DIRS tell the library where to load from. If an attacker can influence those variables — a SUID binary with an unsanitized environment, a shared CI runner, a container that inherits the host's env, a su/sudo invocation with a permissive env_keep — the parser will consume a booby-trapped entry.
You can spot the risky call sites with a few commands. On a Debian/Ubuntu box:
# 1) Which binaries actually link ncurses?
find / -xdev -type f -perm -u+s -exec sh -c '
ldd "$1" 2>/dev/null | grep -q "libncurses\|libtinfo" && printf "SUID+ncurses: %s\n" "$1"
' _ {} \;
# 2) Which processes are currently mapping libtinfo / libncurses?
lsof 2>/dev/null | awk '/libtinfo|libncurses/ {print $1, $2, $NF}' | sort -u
# 3) Are TERMINFO / TERMINFO_DIRS surviving privilege boundaries?
sudo -V | grep -Ei 'env_keep|env_reset'
grep -RIn 'TERMINFO' /etc/sudoers /etc/sudoers.d/ 2>/dev/null
If step 1 returns any SUID binary, you have a candidate for the CVE-2000-0963 / CVE-2002-0062 class regardless of the year on the CVE. If step 3 shows TERMINFO* in env_keep, that is the finding — you do not need a working PoC to file the ticket.
The 2017 cluster: crafted terminfo, not just long env vars
CVE-2017-10684 through CVE-2017-13729 are subtler. They don't require an env var; they require the parser to read a malicious compiled terminfo entry. That happens whenever an ncurses-linked program is asked to describe an unknown terminal, or whenever tic/infocmp is pointed at attacker-controlled data.
This goes wrong in predictable places:
- CI runners that let a job set
TERMand drop a~/.terminfo/x/xfoofile that a later step parses. - Shared-hosting shells where users can create
~/.terminfoentries that root-owned tooling (backup agents, monitoring, MOTD scripts) later reads. - Container base images pinned to distro releases that shipped ncurses 6.0 without the 2017 backports.
libtinfo6in older Debian/Ubuntu LTS images is the usual suspect. - Embedded devices where a BusyBox userland depends on an ncurses build branched years ago and never rebased.
The DoS-only entries (CVE-2017-11112, CVE-2017-11113, CVE-2017-13728, CVE-2017-13729) are the ones defenders underweight. On a build farm or a bastion, a parser that infinite-loops or dereferences NULL on demand gives a low-privileged tenant a cheap way to knock over a shared service. "Only a DoS" stops meaning "only a DoS" the moment the affected process is a health checker whose absence triggers an auto-heal that reboots a node an attacker is about to log into.
What to actually do this week
- Inventory ncurses. Every host, every container image, every appliance.
dpkg -l | grep -E 'ncurses|tinfo'andrpm -qa | grep -E 'ncurses|tinfo'cover 90% of the fleet. Feed the versions into your SBOM diff. - Confirm fix pedigree. Upstream fixes landed in ncurses 6.0-20170729; distros followed with their own patch series. If your image predates that with no vendor backport, patch or rebuild.
- **Strip
TERMINFO*at privilege boundaries.**sudoersshould haveenv_resetenabled and neitherTERMINFOnorTERMINFO_DIRSinenv_keep.su -is not automatic protection — audit the PAM stack. - Constrain
~/.terminfoon multi-tenant hosts. If root-owned services parse user-writable terminfo entries, drop privileges before the parse or point the tool at a hardenedTERMINFOprefix locked withchattr +i. - Fuzz the boundary you own. If you ship a CLI or TUI that ingests external data and passes it to ncurses, add an
AFL++/libFuzzerharness againstsetupterm()andtigetstr(). The 2017 crashes reproduce cheaply; regressions will too.
Old CVEs aren't "resolved" — they're dormant. The parser under your terminal deserves the same scrutiny you give your JSON, YAML, and XML paths. Teams that use legacy library CVEs to trace where their tooling reads untrusted bytes ship fewer incidents than teams that grade risk by CVSS and stop reading at 0.0.
Patch the images, strip the env, fuzz the seam.
Verifiable security.