{"id":"CVE-2026-128343","kind":"vulnerability","aliases":["CVE-2026-128343"],"related":[],"title":"exceljs through 4.4.0: XLSX with a huge row number blocks the Node event loop (fix only in exceljs-hardened 5.1.0)","description":"exceljs through 4.4.0 contains a denial of service vulnerability that allows attackers to block the event loop by supplying unbounded row r attributes parsed in row-xform.js. Attackers can craft an XLSX file with a row numbered far beyond Excel's limit, making getSheetValues(), workbook writes and CSV export consume time proportional to that number.","summary":"exceljs through 4.4.0 parses the row attribute of XLSX files without a bound, so a row numbered far beyond Excel's limit is accepted. Processing such a file makes getSheetValues(), workbook writes and CSV export consume time proportional to that number, blocking the event loop.","severity":"high","cvss":8.7,"epss":null,"exploited":false,"exploited_at":null,"products":[{"name":"exceljs","fixed":[],"affected":"<= 4.4.0","ecosystem":"npm"},{"name":"exceljs-hardened","fixed":["5.1.0"],"affected":"<= 5.0.2","ecosystem":"npm"}],"ecosystems":[],"tags":["exceljs","exceljs-hardened","node","npm","package","xlsx-upload"],"not_affected_if":["no-xlsx-parsing","trusted-input-only"],"how_to_check":"Run `npm ls exceljs exceljs-hardened`. exceljs <= 4.4.0 is affected, with no upstream fix found. exceljs-hardened <= 5.0.2 is affected, and 5.1.0 is fixed. Then look for code that reads untrusted XLSX through exceljs (wb.xlsx.load/readFile, getSheetValues, xlsx.writeBuffer, csv.writeBuffer). A test file puts <row r=\"20000000\"> in xl/worksheets/sheet1.xml. The advisory reports about 0.6 s for getSheetValues, 1.2 s for an xlsx write and 6.2 s for CSV at that row number, growing linearly.","fix":"exceljs-hardened: upgrade to 5.1.0 (maintainer advisory). Upstream exceljs: no patched release found; 4.4.0 is the latest on its releases page. Until then, reject or cap row numbers (Excel's maximum is 1,048,576) before parsing untrusted XLSX, or run parsing in a worker or separate process with a timeout. Or switch to exceljs-hardened 5.1.0.","status":"open","published_at":"2026-11-13T10:18:14+00:00","first_seen_at":"2026-11-13T10:47:34+00:00","triaged_at":"2026-11-13T10:49:15+00:00","updated_at":"2026-11-13T10:50:02+00:00","category":"package","confidence":0.8,"triage":{"at":"2026-11-13T10:49:15Z","model":"claude-haiku-5-5","output":{"fix":"unknown","reach":"internet","title":"exceljs: crafted XLSX row number blocks Node event loop, denial of service","impact":"low","summary":"exceljs through 4.4.0 parses the row attribute of XLSX files without a bound, so a row numbered far beyond Excel's limit is accepted. Processing such a file makes getSheetValues(), workbook writes and CSV export consume time proportional to that number, blocking the event loop.","audience":"developers","category":"package","nicknames":[],"who_cares":["exceljs","node","xlsx-upload"],"confidence":0.6,"fix_status":"unknown","needs_auth":"no","worst_case":"Attacker stalls the Node.js event loop, causing denial of service.","analyst_note":"Fixed version not stated in the sources; check the exceljs GitHub advisory and the vendor advisory linked on github.com for a patched release.","how_to_check":"- Check the installed version with `npm ls exceljs` and treat `4.4.0` and earlier as affected.\n- Search for code that reads uploaded or external XLSX files with exceljs (`getSheetValues`, `csv.write`, workbook read).","plain_action":"","product_name":"","needs_analyst":true,"not_affected_if":["trusted-input-only","no-xlsx-parsing"],"who_is_affected":"Applications that parse XLSX files supplied by users or external systems with exceljs, particularly servers that handle uploads. Projects that only generate spreadsheets from trusted data are unlikely to be exposed. The sources do not state a fixed version.","user_interaction":"no","product_ecosystem":"","needs_special_setup":"no","severity_if_unknown":"high"},"cost_usd":0.000746,"input_tokens":4611,"output_tokens":569,"severity_before":"high"},"analyst_status":"done","analyst_note":"Fixed version not stated in the sources; check the exceljs GitHub advisory and the vendor advisory linked on github.com for a patched release.","search":"'-128343':24A,27A '-2026':23A,26A '4.4.0':3A,44B,89C '5.1.0':21A 'accept':65B 'allow':97C 'attack':98C,113C 'attribut':48B,109C 'beyond':60B,124C 'block':10A,83B,100C 'bound':54B 'consum':77B,135C 'contain':90C 'craft':115C 'csv':75B,133C 'cve':22A,25A 'denial':92C 'event':13A,85B,102C 'excel':61B,125C 'excelj':1A,19A,32B,34B,42B,87C 'exceljs':28A,30A 'exceljs-harden':18A,33B 'exceljs-hardened':29A 'export':76B,134C 'far':59B,123C 'file':51B,69B,118C 'fix':15A 'getsheetvalu':71B,129C 'harden':20A,35B 'hardened':31A 'huge':7A 'limit':63B,127C 'loop':14A,86B,103C 'make':70B,128C 'node':12A,36B 'npm':37B 'number':9A,58B,82B,122C,140C 'packag':38B 'pars':45B,110C 'process':66B 'proport':79B,137C 'r':108C 'row':8A,47B,57B,107C,121C 'row-xform.js':112C 'servic':94C 'suppli':105C 'time':78B,136C 'unbound':106C 'upload':41B 'vulner':95C 'without':52B 'workbook':72B,130C 'write':73B,131C 'xlsx':4A,40B,50B,117C 'xlsx-upload':39B","nicknames":[],"mitigations":[],"who_affected":"Node services that parse XLSX files from users or outside systems with exceljs (<= 4.4.0) or exceljs-hardened (<= 5.0.2). Typical examples are upload, import and report-conversion endpoints. An attacker needs no login if the endpoint is public. The file loads fast, and every later read, write or CSV export blocks the event loop for a time proportional to the row number. Apps that only generate spreadsheets from trusted data can skip it.","tier":"B","verified":{"fix":{"at":"2026-11-13T10:50:02Z","by":"analyst","doc":"https://github.com/mateocallec/exceljs-hardened/security/advisories/GHSA-3gm5-qxj8-89rr","run_id":3855}},"analyst_revisit_at":null,"fix_status":"none","audience":"developers","plain_action":null,"pkeys":["exceljs","exceljshardened"],"ptokens":["exceljs","hardened"],"labels":["exceljs","exceljshardened","high","node","npm","package","xlsxupload"],"campaign_type":null,"search_a":"'-128343':24A,27A '-2026':23A,26A '4.4.0':3A '5.1.0':21A 'block':10A 'cve':22A,25A 'event':13A 'excelj':1A,19A 'exceljs':28A,30A 'exceljs-harden':18A 'exceljs-hardened':29A 'fix':15A 'harden':20A 'hardened':31A 'huge':7A 'loop':14A 'node':12A 'number':9A 'row':8A 'xlsx':4A","search_b":"'4.4.0':44B 'accept':65B 'attribut':48B 'beyond':60B 'block':83B 'bound':54B 'consum':77B 'csv':75B 'event':85B 'excel':61B 'excelj':32B,34B,42B 'exceljs-harden':33B 'export':76B 'far':59B 'file':51B,69B 'getsheetvalu':71B 'harden':35B 'limit':63B 'loop':86B 'make':70B 'node':36B 'npm':37B 'number':58B,82B 'packag':38B 'pars':45B 'process':66B 'proport':79B 'row':47B,57B 'time':78B 'upload':41B 'without':52B 'workbook':72B 'write':73B 'xlsx':40B,50B 'xlsx-upload':39B","search_c":"'4.4.0':89C 'allow':97C 'attack':98C,113C 'attribut':109C 'beyond':124C 'block':100C 'consum':135C 'contain':90C 'craft':115C 'csv':133C 'denial':92C 'event':102C 'excel':125C 'excelj':87C 'export':134C 'far':123C 'file':118C 'getsheetvalu':129C 'limit':127C 'loop':103C 'make':128C 'number':122C,140C 'pars':110C 'proport':137C 'r':108C 'row':107C,121C 'row-xform.js':112C 'servic':94C 'suppli':105C 'time':136C 'unbound':106C 'vulner':95C 'workbook':130C 'write':131C 'xlsx':117C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-10-16T16:05:44+00:00","kev":null,"cvss_vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/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":"disclosure@vulncheck.com","poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2026-128343","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-128343","severity":null,"published_at":"2026-11-13T10:18:14+00:00","modified_at":"2026-11-13T10:18:14+00:00","first_seen_at":"2026-11-13T10:47:34+00:00","fetched_at":"2026-11-13T10:47:34+00:00","note":null},{"source":"analyst","external_id":"CVE-2026-128343:3855","url":null,"severity":null,"published_at":"2026-11-13T10:50:02+00:00","modified_at":"2026-11-13T10:50:02+00:00","first_seen_at":"2026-11-13T10:50:02+00:00","fetched_at":"2026-11-13T10:50:02+00:00","note":"GHSA-3gm5-qxj8-89rr is published on the exceljs-hardened fork (<=5.0.2, patched 5.1.0). It is not an upstream exceljs advisory. The upstream releases page lists 4.4.0 as the latest release and no fix. PoC with timings is in the advisory."}],"documents":[{"id":145487,"url":"https://github.com/mateocallec/exceljs-hardened/security/advisories/GHSA-3gm5-qxj8-89rr","title":"Vendor advisory: github.com","kind":"vendor","source":"nvd","publisher":"vendor","text":null,"published_at":"2026-10-16T16:05:44+00:00","relation":"advisory","confidence":null,"note":"Vendor advisory: github.com"},{"id":145488,"url":"https://www.vulncheck.com/advisories/exceljs-through-4.4.0-denial-of-service-via-oversized-row-number","title":"Third-party advisory: www.vulncheck.com","kind":"advisory","source":"nvd","publisher":"research","text":null,"published_at":null,"relation":"advisory","confidence":null,"note":"Third-party advisory: www.vulncheck.com"}],"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"}