{"id":"CVE-2026-121750","kind":"vulnerability","aliases":["CVE-2026-121750"],"related":[],"title":"nvm: rejected Node.js archive stays cached and can still be installed","description":"Node Version Manager (nvm) is a POSIX-compliant shell function for managing multiple node.js versions. In versions 0.40.5 through 0.40.8, `nvm_download_artifact` downloads a release archive directly to its final path in `$NVM_DIR/.cache` and verifies its checksum afterwards; on a checksum mismatch it reports an error but leaves the rejected archive in place. A later `nvm install --offline` of the same version installs that cached file without a checksum, so an archive that was just rejected gets installed and its `node` and `npm` run. This gives code execution to a party who can alter the downloaded tarball (for example a poisoned CDN or cache object) but cannot also forge the `SHASUMS256.txt` beside it, if the victim runs `nvm install --offline` for that version after the visible \"Checksums do not match\" failure and before any online retry. Version 0.41.0 only puts an archive in the cache once its checksum has passed.","summary":"nvm versions 0.40.5 through 0.40.8 keep a Node.js archive in its cache even after its checksum fails, and a later offline install uses that archive without checking it again. An attacker who can alter the downloaded tarball but cannot forge the checksum file can get their code run as node and npm on the victim's machine.","severity":"low","cvss":3.1,"epss":null,"exploited":false,"exploited_at":null,"products":[],"ecosystems":[],"tags":["ci","developers","node","nvm","package"],"not_affected_if":["no-offline-install","nvm-0.41.0-or-later","trusted-download-path"],"how_to_check":"- Run `nvm --version` and check whether it reports a version from `0.40.5` to `0.40.8`\n- Look for leftover archives in `$NVM_DIR/.cache` after a failed install\n- Check whether anyone runs `nvm install --offline` in scripts or CI","fix":"- nvm `0.41.0` only caches an archive once its checksum has passed","status":"open","published_at":"2026-11-04T22:17:54+00:00","first_seen_at":"2026-11-04T23:08:47+00:00","triaged_at":"2026-11-04T23:10:13+00:00","updated_at":"2026-11-04T23:10:13+00:00","category":"package","confidence":0.7,"triage":{"at":"2026-11-04T23:10:13Z","model":"claude-haiku-5-5","output":{"fix":"- nvm `0.41.0` only caches an archive once its checksum has passed","reach":"network","title":"nvm: rejected Node.js archive stays cached and can still be installed","impact":"high","summary":"nvm versions 0.40.5 through 0.40.8 keep a Node.js archive in its cache even after its checksum fails, and a later offline install uses that archive without checking it again. An attacker who can alter the downloaded tarball but cannot forge the checksum file can get their code run as node and npm on the victim's machine.","audience":"developers","category":"package","nicknames":[],"who_cares":["nvm","node","developers","ci"],"confidence":0.7,"fix_status":"available","needs_auth":"no","worst_case":"code runs as the victim's node and npm user","analyst_note":"Confirm the affected range and the patch commit at the linked GitHub advisory, which the sources list but do not quote here.","how_to_check":"- Run `nvm --version` and check whether it reports a version from `0.40.5` to `0.40.8`\n- Look for leftover archives in `$NVM_DIR/.cache` after a failed install\n- Check whether anyone runs `nvm install --offline` in scripts or CI","plain_action":"","needs_analyst":true,"not_affected_if":["nvm-0.41.0-or-later","no-offline-install","trusted-download-path"],"who_is_affected":"Developers and build machines that use nvm 0.40.5 through 0.40.8 to install Node.js. Exposure needs an attacker who can alter the downloaded tarball, such as a poisoned CDN or cache object, while the checksum file stays intact, and a victim who runs an offline install after a checksum failure. Machines on 0.41.0 or later, or that never run `nvm install --offline`, can skip it.","user_interaction":"yes","needs_special_setup":"yes","severity_if_unknown":"unknown"},"cost_usd":0.000773,"input_tokens":4467,"output_tokens":652,"severity_before":"low"},"analyst_status":null,"analyst_note":null,"search":"'-121750':14A,17A '-2026':13A,16A '0.40.5':25B,98C '0.40.8':27B,100C '0.41.0':220C 'afterward':120C 'also':190C 'alter':56B,176C 'archiv':4A,31B,47B,107C,133C,154C,224C 'artifact':103C 'attack':53B 'besid':194C 'cach':6A,34B,147C,186C,227C 'cannot':61B,189C 'cdn':184C 'check':49B 'checksum':38B,64B,119C,123C,151C,209C,230C 'ci':18B 'code':69B,169C 'compliant':88C 'cve':12A,15A 'develop':19B 'dir/.cache':115C 'direct':108C 'download':58B,102C,104C,178C 'error':128C 'even':35B 'exampl':181C 'execut':170C 'fail':39B 'failur':213C 'file':65B,148C 'final':111C 'forg':62B,191C 'function':90C 'get':67B,159C 'give':168C 'instal':11A,44B,139C,145C,160C,201C 'keep':28B 'later':42B,137C 'leav':130C 'machin':79B 'manag':82C,92C 'match':212C 'mismatch':124C 'multipl':93C 'node':20B,72B,80C,163C 'node.js':3A,30B,94C 'npm':74B,165C 'nvm':1A,21B,23B,83C,101C,114C,138C,200C 'object':187C 'offlin':43B,140C,202C 'onlin':217C 'packag':22B 'parti':173C 'pass':232C 'path':112C 'place':135C 'poison':183C 'posix':87C 'posix-compli':86C 'put':222C 'reject':2A,132C,158C 'releas':106C 'report':126C 'retri':218C 'run':70B,166C,199C 'shasums256.txt':193C 'shell':89C 'stay':5A 'still':9A 'tarbal':59B,179C 'use':45B 'verifi':117C 'version':24B,81C,95C,97C,144C,205C,219C 'victim':77B,198C 'visibl':208C 'without':48B,149C","nicknames":[],"mitigations":[],"who_affected":"Developers and build machines that use nvm 0.40.5 through 0.40.8 to install Node.js. Exposure needs an attacker who can alter the downloaded tarball, such as a poisoned CDN or cache object, while the checksum file stays intact, and a victim who runs an offline install after a checksum failure. Machines on 0.41.0 or later, or that never run `nvm install --offline`, can skip it.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"developers","plain_action":null,"pkeys":[],"ptokens":[],"labels":["ci","developers","low","node","nvm","package"],"campaign_type":null,"first_public_at":"2026-11-04T21:28:36+00:00","kev":null,"cvss_vector":"CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:A/VC:N/VI:L/VA:N/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-121750","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-121750","severity":null,"published_at":"2026-11-04T22:17:54+00:00","modified_at":"2026-11-04T22:17:54+00:00","first_seen_at":"2026-11-04T23:08:47+00:00","fetched_at":"2026-11-04T23:08:47+00:00","note":null}],"documents":[{"id":71140,"url":"https://github.com/nvm-sh/nvm/commit/1f99e4c20bb92c5737b92512446acf8e303b1edd","title":"Patch: github.com","kind":"other","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":71141,"url":"https://github.com/nvm-sh/nvm/security/advisories/GHSA-262q-c465-prmr","title":"Vendor advisory: github.com","kind":"vendor","source":"nvd","publisher":"vendor","text":null,"published_at":"2026-11-04T21:28:36+00:00","relation":"advisory","confidence":null,"note":"Vendor advisory: github.com"}],"exploit_sources":[],"notice":"Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai"}