{"id":"CVE-2026-118905","kind":"vulnerability","aliases":["CVE-2026-118905"],"related":[],"title":"nvm: crafted version string or .nvmrc runs shell commands as user","description":"Node Version Manager (nvm) is a POSIX-compliant shell function for managing multiple node.js versions. In versions 0.31.2 through 0.40.5, `nvm_ls` filters installed versions with a sed program that embeds the requested version pattern in a `\\#...#` address, escaping `.` (and, since 0.40.4, `#`) but not backslash. A version string containing `#` (or `\\#`) therefore closes the address early, and the rest of it is parsed as sed commands: with GNU sed, the `e` command runs a shell command as the user; with BSD sed, the `w` and `r` commands write and read files. This is reachable whenever an attacker-influenced version string is passed to `nvm use`, `nvm which`, `nvm ls`, `nvm version`, `nvm run`, or `nvm exec`, or to `nvm-exec` via `NODE_VERSION`, and at least one version is installed. nvm's own `.nvmrc` parser strips comments, so a bare `nvm use` is not affected; however, the bash `cdnvm` and zsh `load-nvmrc` auto-switch hooks documented in the README read `.nvmrc` as-is and pass it to `nvm ls` and `nvm version`, so a user with one of those hooks installed runs the attacker's command just by changing into a directory under a malicious `.nvmrc`; scripts that run `nvm use \"$(cat .nvmrc)\"` are affected the same way. Version 0.40.6 passes any version pattern containing `#` or a newline through the `.nvmrc` content parser first, so no `#` reaches the sed program.","summary":"Versions 0.31.2 through 0.40.5 of nvm build a sed program from the requested version string without escaping backslashes, so a '#' in that string lets an attacker inject sed commands. With GNU sed this runs a shell command as the user; with BSD sed it can read and write files.","severity":"high","cvss":7.1,"epss":null,"exploited":false,"exploited_at":null,"products":[],"ecosystems":[],"tags":["ci","developer-workstations","node.js","nvm","package","shell"],"not_affected_if":["no-auto-switch-hook","no-untrusted-nvmrc","version-0.40.6-or-later"],"how_to_check":"- Run `nvm --version` and check whether it falls in 0.31.2 through 0.40.5.\n- Check whether a bash `cdnvm` or zsh `load-nvmrc` hook is installed in shell startup files, since those read `.nvmrc` files automatically.\n- Check whether scripts run `nvm use \"$(cat .nvmrc)\"` on untrusted repositories.","fix":null,"status":"open","published_at":"2026-10-29T06:17:20+00:00","first_seen_at":"2026-10-29T06:53:13+00:00","triaged_at":"2026-10-29T06:54:30+00:00","updated_at":"2026-10-29T06:54:30+00:00","category":"package","confidence":0.8,"triage":{"at":"2026-10-29T06:54:30Z","model":"claude-haiku-5-5","output":{"fix":"- nvm `0.40.6`: passes any version pattern containing `#` or a newline through the `.nvmrc` content parser first, so no `#` reaches the sed program.","reach":"local","title":"nvm: crafted version string or .nvmrc runs shell commands as user","impact":"high","summary":"Versions 0.31.2 through 0.40.5 of nvm build a sed program from the requested version string without escaping backslashes, so a '#' in that string lets an attacker inject sed commands. With GNU sed this runs a shell command as the user; with BSD sed it can read and write files.","audience":"developers","category":"package","nicknames":[],"who_cares":["nvm","node.js","shell","developer-workstations","ci"],"confidence":0.8,"fix_status":"available","needs_auth":"no","worst_case":"Attacker's shell command runs as the user on their machine","analyst_note":"","how_to_check":"- Run `nvm --version` and check whether it falls in 0.31.2 through 0.40.5.\n- Check whether a bash `cdnvm` or zsh `load-nvmrc` hook is installed in shell startup files, since those read `.nvmrc` files automatically.\n- Check whether scripts run `nvm use \"$(cat .nvmrc)\"` on untrusted repositories.","plain_action":"","needs_analyst":false,"not_affected_if":["version-0.40.6-or-later","no-auto-switch-hook","no-untrusted-nvmrc"],"who_is_affected":"Developers who use nvm on a machine with at least one Node version installed, especially those who use the bash cdnvm or zsh load-nvmrc auto-switch hooks, or scripts that pass `.nvmrc` contents to nvm. An attacker needs a malicious `.nvmrc` or version string to reach the flawed code. Plain `nvm use` with no hook and no untrusted input is not affected per the description.","user_interaction":"yes","needs_special_setup":"yes","severity_if_unknown":"high"},"cost_usd":0.000801,"input_tokens":4558,"output_tokens":691,"severity_before":"high"},"analyst_status":null,"analyst_note":null,"search":"'-118905':14A,17A '-2026':13A,16A '0.31.2':27B,93C '0.40.4':117C '0.40.5':29B,95C '0.40.6':290C 'address':113C,129C 'affect':221C,285C 'as-i':241C 'attack':51B,172C,264C 'attacker-influenc':171C 'auto':232C 'auto-switch':231C 'backslash':43B,120C 'bare':216C 'bash':224C 'bsd':67B,155C 'build':32B 'cat':282C 'cdnvm':225C 'chang':269C 'ci':18B 'close':127C 'command':9A,54B,62B,140C,146C,150C,161C,266C 'comment':213C 'compliant':83C 'contain':124C,295C 'content':302C 'craft':2A 'cve':12A,15A 'develop':20B 'developer-workst':19B 'directori':272C 'document':235C 'e':145C 'earli':130C 'emb':106C 'escap':42B,114C 'exec':191C,196C 'file':74B,165C 'filter':98C 'first':304C 'function':85C 'gnu':56B,142C 'hook':234C,260C 'howev':222C 'influenc':173C 'inject':52B 'instal':99C,206C,261C 'least':202C 'let':49B 'load':229C 'load-nvmrc':228C 'ls':97C,184C,249C 'malici':275C 'manag':77C,87C 'multipl':88C 'newlin':298C 'node':75C,198C 'node.js':22B,89C 'nvm':1A,23B,31B,78C,96C,179C,181C,183C,185C,187C,190C,195C,207C,217C,248C,251C,280C 'nvm-exec':194C 'nvmrc':6A,210C,230C,240C,276C,283C,301C 'one':203C,257C 'packag':24B 'pars':137C 'parser':211C,303C 'pass':177C,245C,291C 'pattern':110C,294C 'posix':82C 'posix-compli':81C 'program':35B,104C,310C 'r':160C 'reach':307C 'reachabl':168C 'read':71B,164C,239C 'readm':238C 'request':38B,108C 'rest':133C 'run':7A,59B,147C,188C,262C,279C 'script':277C 'sed':34B,53B,57B,68B,103C,139C,143C,156C,309C 'shell':8A,25B,61B,84C,149C 'sinc':116C 'string':4A,40B,48B,123C,175C 'strip':212C 'switch':233C 'therefor':126C 'use':180C,218C,281C 'user':11A,65B,153C,255C 'version':3A,26B,39B,76C,90C,92C,100C,109C,122C,174C,186C,199C,204C,252C,289C,293C 'via':197C 'w':158C 'way':288C 'whenev':169C 'without':41B 'workstat':21B 'write':73B,162C 'zsh':227C","nicknames":[],"mitigations":[],"who_affected":"Developers who use nvm on a machine with at least one Node version installed, especially those who use the bash cdnvm or zsh load-nvmrc auto-switch hooks, or scripts that pass `.nvmrc` contents to nvm. An attacker needs a malicious `.nvmrc` or version string to reach the flawed code. Plain `nvm use` with no hook and no untrusted input is not affected per the description.","tier":"B","verified":{},"analyst_revisit_at":null,"fix_status":"unknown","audience":"developers","plain_action":null,"first_public_at":"2026-10-29T06:17:20+00:00","kev":null,"cvss_vector":"CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:A/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","cvss_by":"7ffcee3d-2c14-4c3e-b844-86c6a321a158","poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2026-118905","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-118905","severity":null,"published_at":"2026-10-29T06:17:20+00:00","modified_at":"2026-10-29T06:17:20+00:00","first_seen_at":"2026-10-29T06:53:13+00:00","fetched_at":"2026-10-29T06:53:13+00:00","note":null}],"documents":[],"notice":"Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai"}