{"id":"CVE-2026-112943","kind":"vulnerability","aliases":["CVE-2026-112943","GHSA-698v-4r3x-3vcv"],"related":[],"title":"launch-editor: escapeCmdArgs() omits % escaping on Windows","description":"### Summary\n\n`launch-editor` did not escape `%` on Windows when passing an argument to `cmd`. When an environment variable contained a malicious value, it was possible that that content to be executed.\n\n### Impact\n\nOnly apps that match all of the following conditions are affected:\n\n- The user uses Windows\n- An attacker can place a file with the malicious filename containing `&` or `%`\n- Either of\n  - An attacker can inject an environment variable with a malicious value\n  - An attacker can add a NTFS alternate data stream to the file placed\n\n### Details\n\nUnlike `.sh` files, `.bat` / `.cmd` files on Windows cannot be called directly using [`child_process.spawn`](https://nodejs.org/docs/latest-v24.x/api/child_process.html#child_processspawncommand-args-options) and requires passing them as an argument of `cmd.exe`. To do so, launch-editor escapes the arguments passed to `cmd.exe`. But `launch-editor` did not escape `%` which is used for environment variables.\n\nBecause `launch-editor` checks if the argument matches an existing filename, the attack requires the attacker to be able to place a file.\n\n- If the attacker can inject an environment variable as well, they can include the subcommand in the env variable (e.g. set ` &calc.exe ` to `%ENV%`) and call `launchEditor` with `something%ENV%`.\n- If the attacker can place a NTFS alternate data stream to the file (e.g. a NTFS alternate data stream named `~-38%calc.exe`), they can call `launchEditor` with `something %CMDCMDLINE:~-38%calc.exe`.\n- If the attacker can create a filename containing the `%CD%` and the subcommand (e.g. `&calc.exe `), they can call `launchEditor` with `./%CD%`","summary":"launch-editor, a Node library used by Vite and other dev tools to open files in an editor, does not escape % characters when passing arguments to cmd.exe on Windows. An attacker who can place a specially named file, or inject an environment variable, can get arbitrary commands executed on the developer's machine.","severity":"medium","cvss":6.3,"epss":0.004139999859035015,"exploited":false,"exploited_at":null,"products":[{"name":"launch-editor","fixed":["2.14.2"],"affected":"<= 2.14.1","ecosystem":"npm"},{"name":"vite","fixed":["8.3.3"],"affected":">= 8.3.0, <= 8.3.2","ecosystem":"npm"},{"name":"vite","fixed":["8.2.4"],"affected":">= 8.2.0, <= 8.2.3","ecosystem":"npm"},{"name":"vite","fixed":["8.1.6"],"affected":">= 8.0.0, <= 8.1.5","ecosystem":"npm"},{"name":"vite","fixed":["7.3.7"],"affected":">= 7.0.0, <= 7.3.6","ecosystem":"npm"},{"name":"vite","fixed":["6.4.4"],"affected":"<= 6.4.3","ecosystem":"npm"},{"name":"vite-plus","fixed":["1.1.0"],"affected":"<= 1.0.0","ecosystem":"npm"}],"ecosystems":["npm"],"tags":["cwe-78","developer-machines","launch-editor","node","package","vite","windows"],"not_affected_if":["managed-hosting","no-untrusted-file-writes","non-windows-os"],"how_to_check":"Run npm ls launch-editor and npm ls vite in each project to see installed versions.\nCheck whether the project runs on Windows and whether it uses launchEditor or vite's open-in-editor feature.","fix":"Upgrade launch-editor to 2.14.2 or later, and upgrade vite to the patched line for your major version (8.3.3, 8.2.4, 8.1.6, 7.3.7 or 6.4.4) or vite-plus to 1.1.0.","status":"open","published_at":"2026-10-20T15:17:17+00:00","first_seen_at":"2026-10-23T19:11:32+00:00","triaged_at":"2026-10-23T20:13:33+00:00","updated_at":"2026-10-23T21:57:20+00:00","category":"package","confidence":0.8,"triage":{"at":"2026-10-23T20:13:33Z","model":"claude-haiku-5-5","output":{"fix":"Upgrade launch-editor to 2.14.2 or later, and upgrade vite to the patched line for your major version (8.3.3, 8.2.4, 8.1.6, 7.3.7 or 6.4.4) or vite-plus to 1.1.0.\nunknown for a workaround if you cannot upgrade.","summary":"launch-editor, a Node library used by Vite and other dev tools to open files in an editor, does not escape % characters when passing arguments to cmd.exe on Windows. An attacker who can place a specially named file, or inject an environment variable, can get arbitrary commands executed on the developer's machine.","category":"package","who_cares":["windows","vite","launch-editor","node","developer-machines"],"confidence":0.8,"analyst_note":"","how_to_check":"Run npm ls launch-editor and npm ls vite in each project to see installed versions.\nCheck whether the project runs on Windows and whether it uses launchEditor or vite's open-in-editor feature.\nunknown for any other check the sources do not describe.","needs_analyst":false,"not_affected_if":["non-windows-os","managed-hosting","no-untrusted-file-writes"],"severity_if_unknown":"unknown"},"cost_usd":0.000484,"input_tokens":2748,"output_tokens":418,"severity_before":"medium"},"analyst_status":null,"analyst_note":null,"search":"'-112943':11A,19A '-2026':10A,18A '-38':309C,318C '-78':32B '/docs/latest-v24.x/api/child_process.html#child_processspawncommand-args-options)':200C '3vcv':16A '4r3x':15A '698v':14A 'abl':254C 'add':173C 'affect':140C 'altern':176C,296C,305C 'app':131C 'arbitrari':89B 'argument':68B,109C,207C,218C,242C 'attack':74B,146C,160C,171C,248C,251C,261C,291C,322C 'bat':187C 'calc.exe':280C,310C,319C,334C 'call':194C,284C,313C,337C 'cannot':192C 'cd':329C,340C 'charact':65B 'check':239C 'child_process.spawn':197C 'cmd':111C,188C 'cmd.exe':70B,209C,221C 'cmdcmdline':317C 'command':90B 'condit':138C 'contain':116C,155C,327C 'content':125C 'creat':324C 'cve':9A,17A 'cwe':31B 'data':177C,297C,306C 'detail':183C 'dev':54B 'develop':34B,94B 'developer-machin':33B 'direct':195C 'e.g':278C,302C,333C 'editor':3A,22A,38B,45B,61B,100C,215C,225C,238C 'either':157C 'env':276C,282C,288C 'environ':85B,114C,164C,233C,265C 'escap':6A,64B,103C,216C,228C 'escapecmdarg':4A 'execut':91B,128C 'exist':245C 'file':58B,81B,150C,181C,186C,189C,258C,301C 'filenam':154C,246C,326C 'follow':137C 'get':88B 'ghsa':13A 'ghsa-698v-4r3x-3vcv':12A 'impact':129C 'includ':271C 'inject':83B,162C,263C 'launch':2A,21A,37B,44B,99C,214C,224C,237C 'launch-editor':1A,20A,36B,43B,98C,213C,223C,236C 'launcheditor':285C,314C,338C 'librari':48B 'machin':35B,96B 'malici':118C,153C,168C 'match':133C,243C 'name':80B,308C 'node':39B,47B 'nodejs.org':199C 'nodejs.org/docs/latest-v24.x/api/child_process.html#child_processspawncommand-args-options)':198C 'ntfs':175C,295C,304C 'omit':5A 'open':57B 'packag':40B 'pass':67B,107C,203C,219C 'place':77B,148C,182C,256C,293C 'plus':30A 'possibl':122C 'requir':202C,249C 'set':279C 'sh':185C 'someth':287C,316C 'special':79B 'stream':178C,298C,307C 'subcommand':273C,332C 'summari':97C 'tool':55B 'unlik':184C 'use':49B,143C,196C,231C 'user':142C 'valu':119C,169C 'variabl':86B,115C,165C,234C,266C,277C 'vite':23A,24A,25A,26A,27A,29A,41B,51B 'vite-plus':28A 'well':268C 'window':8A,42B,72B,105C,144C,191C","nicknames":[],"mitigations":[],"who_affected":null,"tier":"C","verified":{},"analyst_revisit_at":null,"first_public_at":"2026-10-20T15:17:17+00:00","kev":null,"cvss_vector":"CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:L/VA:L/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":"security-advisories@github.com","poc_count":0,"sources":[{"source":"ghsa","external_id":"GHSA-698v-4r3x-3vcv","url":"https://github.com/advisories/GHSA-698v-4r3x-3vcv","severity":"medium","published_at":"2026-10-20T18:30:24+00:00","modified_at":"2026-10-20T18:30:25+00:00","first_seen_at":"2026-10-23T19:11:32+00:00","fetched_at":"2026-10-23T19:11:32+00:00","note":null},{"source":"nvd","external_id":"CVE-2026-112943","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-112943","severity":null,"published_at":"2026-10-20T15:17:17+00:00","modified_at":"2026-10-20T19:55:49+00:00","first_seen_at":"2026-10-23T21:57:20+00:00","fetched_at":"2026-10-23T22:28:58+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"}