{"id":"CVE-2026-123829","kind":"vulnerability","aliases":["CVE-2026-123829"],"related":[],"title":"Node.js: recursive file watching leaks names of files it should not read","description":"A Permission Model bypass in Node.js recursive file watching discloses the names of files and directories the process is not permitted to read. On macOS and Windows, fs.watch() and fs.promises.watch() in recursive mode are backed by the native libuv watcher: FSEventWrap::Start checks kFileSystemRead only once, on the watched root, and FSEventWrap::OnEvent then forwards every filename libuv reports (relative paths at any depth) to the JavaScript callback without checking that each path is covered by the read grant. Code running under --permission with an exact read grant on a directory can therefore learn names such as sub/secret.txt even though readdir on that subdirectory is denied. The flaw exposes names and timing metadata, not file contents, and requires macOS or Windows plus files created under the watched directory by another actor. This vulnerability affects Node.js 26.x, 24.x, and 22.x.","summary":"On macOS and Windows, recursive fs.watch() in Node.js reports the names of files in subdirectories that the Permission Model should block. An attacker-controlled process gets file and directory names and timing, but not file contents.","severity":"low","cvss":2.5,"epss":null,"exploited":false,"exploited_at":null,"products":[],"ecosystems":[],"tags":["macos","node.js","permission-model","runtime","windows"],"not_affected_if":["linux","managed-hosting","no-permission-flag","non-recursive-watch"],"how_to_check":"- Run `node --version` and compare against the affected lines 22.x, 24.x and 26.x\n- Check whether the app runs with `--permission` and uses `fs.watch()` or `fs.promises.watch()` with `recursive: true` on macOS or Windows","fix":null,"status":"open","published_at":"2026-11-11T19:17:32+00:00","first_seen_at":"2026-11-11T19:28:45+00:00","triaged_at":"2026-11-11T19:30:47+00:00","updated_at":"2026-11-11T19:30:47+00:00","category":"runtime","confidence":0.7,"triage":{"at":"2026-11-11T19:30:47Z","model":"claude-haiku-5-5","output":{"fix":"unknown","reach":"local","title":"Node.js: recursive file watching leaks names of files it should not read","impact":"low","summary":"On macOS and Windows, recursive fs.watch() in Node.js reports the names of files in subdirectories that the Permission Model should block. An attacker-controlled process gets file and directory names and timing, but not file contents.","audience":"developers","category":"runtime","nicknames":[],"who_cares":["node.js","macos","windows","permission-model"],"confidence":0.7,"fix_status":"unknown","needs_auth":"unknown","worst_case":"Attacker learns file and directory names in restricted subfolders","analyst_note":"Find the fixed Node.js versions for 22.x, 24.x and 26.x in the Node.js security release notes; the sources here give none.","how_to_check":"- Run `node --version` and compare against the affected lines 22.x, 24.x and 26.x\n- Check whether the app runs with `--permission` and uses `fs.watch()` or `fs.promises.watch()` with `recursive: true` on macOS or Windows","plain_action":"","product_name":"","needs_analyst":true,"not_affected_if":["linux","no-permission-flag","non-recursive-watch","managed-hosting"],"who_is_affected":"Only Node.js programs that run under the --permission Permission Model, grant read access to a directory, and call recursive fs.watch on macOS or Windows where other actors create files in that directory. Servers on Linux, or apps that do not use the Permission Model, are not exposed by this flaw. The sources do not name a fixed Node.js version.","user_interaction":"no","product_ecosystem":"","needs_special_setup":"yes","severity_if_unknown":"low"},"cost_usd":0.000771,"input_tokens":4744,"output_tokens":594,"severity_before":"low"},"analyst_status":null,"analyst_note":null,"search":"'-123829':15A,18A '-2026':14A,17A '22':203C '24':200C '26':198C 'actor':193C 'affect':196C 'anoth':192C 'attack':49B 'attacker-control':48B 'back':97C 'block':46B 'bypass':66C 'callback':130C 'check':105C,132C 'code':142C 'content':62B,178C 'control':50B 'cover':137C 'creat':186C 'cve':13A,16A 'deni':168C 'depth':126C 'directori':55B,78C,153C,190C 'disclos':72C 'even':161C 'everi':118C 'exact':148C 'expos':171C 'file':3A,8A,38B,53B,61B,70C,76C,177C,185C 'filenam':119C 'flaw':170C 'forward':117C 'fs.promises.watch':92C 'fs.watch':31B,90C 'fseventwrap':103C,114C 'get':52B 'grant':141C,150C 'javascript':129C 'kfilesystemread':106C 'leak':5A 'learn':156C 'libuv':101C,120C 'maco':19B,27B,87C,181C 'metadata':175C 'mode':95C 'model':23B,44B,65C 'name':6A,36B,56B,74C,157C,172C 'nativ':100C 'node.js':1A,20B,33B,68C,197C 'onev':115C 'path':123C,135C 'permiss':22B,43B,64C,145C 'permission-model':21B 'permit':83C 'plus':184C 'process':51B,80C 'read':12A,85C,140C,149C 'readdir':163C 'recurs':2A,30B,69C,94C 'relat':122C 'report':34B,121C 'requir':180C 'root':112C 'run':143C 'runtim':24B 'start':104C 'sub/secret.txt':160C 'subdirectori':40B,166C 'therefor':155C 'though':162C 'time':58B,174C 'vulner':195C 'watch':4A,71C,111C,189C 'watcher':102C 'window':25B,29B,89C,183C 'without':131C 'x':199C,201C,204C","nicknames":[],"mitigations":[],"who_affected":"Only Node.js programs that run under the --permission Permission Model, grant read access to a directory, and call recursive fs.watch on macOS or Windows where other actors create files in that directory. Servers on Linux, or apps that do not use the Permission Model, are not exposed by this flaw. The sources do not name a fixed Node.js version.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"none","audience":"developers","plain_action":null,"pkeys":[],"ptokens":[],"labels":["low","macos","nodejs","permissionmodel","runtime","windows"],"campaign_type":null,"search_a":"'-123829':15A,18A '-2026':14A,17A 'cve':13A,16A 'file':3A,8A 'leak':5A 'name':6A 'node.js':1A 'read':12A 'recurs':2A 'watch':4A","search_b":"'attack':49B 'attacker-control':48B 'block':46B 'content':62B 'control':50B 'directori':55B 'file':38B,53B,61B 'fs.watch':31B 'get':52B 'maco':19B,27B 'model':23B,44B 'name':36B,56B 'node.js':20B,33B 'permiss':22B,43B 'permission-model':21B 'process':51B 'recurs':30B 'report':34B 'runtim':24B 'subdirectori':40B 'time':58B 'window':25B,29B","search_c":"'22':203C '24':200C '26':198C 'actor':193C 'affect':196C 'anoth':192C 'back':97C 'bypass':66C 'callback':130C 'check':105C,132C 'code':142C 'content':178C 'cover':137C 'creat':186C 'deni':168C 'depth':126C 'directori':78C,153C,190C 'disclos':72C 'even':161C 'everi':118C 'exact':148C 'expos':171C 'file':70C,76C,177C,185C 'filenam':119C 'flaw':170C 'forward':117C 'fs.promises.watch':92C 'fs.watch':90C 'fseventwrap':103C,114C 'grant':141C,150C 'javascript':129C 'kfilesystemread':106C 'learn':156C 'libuv':101C,120C 'maco':87C,181C 'metadata':175C 'mode':95C 'model':65C 'name':74C,157C,172C 'nativ':100C 'node.js':68C,197C 'onev':115C 'path':123C,135C 'permiss':64C,145C 'permit':83C 'plus':184C 'process':80C 'read':85C,140C,149C 'readdir':163C 'recurs':69C,94C 'relat':122C 'report':121C 'requir':180C 'root':112C 'run':143C 'start':104C 'sub/secret.txt':160C 'subdirectori':166C 'therefor':155C 'though':162C 'time':174C 'vulner':195C 'watch':71C,111C,189C 'watcher':102C 'window':89C,183C 'without':131C 'x':199C,201C,204C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-11-11T19:17:32+00:00","kev":null,"cvss_vector":"CVSS:3.0/AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:N","cvss_by":"ce714d77-add3-4f53-aff5-83d477b104bb","poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2026-123829","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-123829","severity":null,"published_at":"2026-11-11T19:17:32+00:00","modified_at":"2026-11-11T19:17:32+00:00","first_seen_at":"2026-11-11T19:28:45+00:00","fetched_at":"2026-11-11T19:28:45+00:00","note":null}],"documents":[],"disclosures":[],"exploit_sources":[],"notice":"Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai"}