SECURITYCRITICALCVE-2026-78207

CVE-2026-78207: Critical Prototype Pollution in exceljs-hardened Before v5.0.0

A CVSS 9.4 prototype pollution vulnerability in exceljs-hardened's deepMerge helper allows attackers to corrupt Object.prototype via crafted XLSX files.

Dylan H.

Security Team

August 24, 2026
3 min read
CVE-2026-78207: Critical Prototype Pollution in exceljs-hardened Before v5.0.0

Critical severity

Rated critical. Prioritise patching — see the remediation guidance below.

Affected Products

  • exceljs-hardened < 5.0.0

Overview

CVE-2026-78207 is a critical-severity prototype pollution vulnerability (CVSS 9.4) affecting exceljs-hardened before version 5.0.0. The flaw exists in the library's internal deepMerge helper function, which fails to reject reserved JavaScript keys — specifically __proto__, constructor, and prototype — when merging note objects parsed from XLSX cell data.

A remote attacker who can supply a crafted spreadsheet file containing a malicious __proto__ property in a cell note can corrupt Object.prototype globally within the Node.js process, potentially achieving remote code execution (RCE) or arbitrary property injection that cascades through the application.

Affected Versions

PackageAffectedFixed
exceljs-hardened (npm)< 5.0.05.0.0+

Vulnerability Details

Root Cause

The deepMerge utility in exceljs-hardened recursively merges parsed JSON data from XLSX cell notes into JavaScript objects. Before v5.0.0, it did not sanitize or block keys like __proto__, constructor, or prototype. When an attacker provides an XLSX file with a cell note containing:

{
  "__proto__": {
    "isAdmin": true,
    "polluted": "attacker-controlled-value"
  }
}

The merge operation walks the __proto__ key directly onto Object.prototype, affecting all objects in the process from that point forward.

Impact

Successful exploitation allows an attacker to:

  • Corrupt Object.prototype — all subsequently created objects inherit attacker-controlled properties
  • Achieve RCE — in environments where polluted properties influence code execution paths (e.g., template engines, child_process.spawn option resolution, configuration loading)
  • Bypass authorization logic — applications checking properties like isAdmin or hasPermission may evaluate to true for all users after pollution

This vulnerability is particularly dangerous in server-side Node.js environments that parse user-supplied Excel files, such as document upload services, financial data processors, and ETL pipelines.

Attack Vector

The attack requires the victim application to:

  1. Accept an XLSX file as user input
  2. Parse the file using exceljs-hardened (e.g., via workbook.xlsx.load())
  3. Process cell notes (the vulnerable code path)

No authentication is required if the XLSX upload endpoint is publicly accessible, making this exploitable by unauthenticated remote attackers in many real-world deployments.

Proof of Concept

The general technique involves crafting an XLSX file where a cell note's XML content deserializes to an object with a __proto__ key. Conceptually:

// Vulnerable code path (simplified, pre-patch)
function deepMerge(target, source) {
  for (const key of Object.keys(source)) {
    // BUG: no check for __proto__, constructor, prototype
    if (typeof source[key] === 'object') {
      target[key] = deepMerge(target[key] || {}, source[key]);
    } else {
      target[key] = source[key];
    }
  }
  return target;
}

After pollution, all newly created empty objects inherit attacker properties:

const obj = {};
console.log(obj.isAdmin); // true (after pollution)

Remediation

Upgrade immediately to exceljs-hardened v5.0.0 or later.

The patch introduces key sanitization in deepMerge, explicitly rejecting __proto__, constructor, and prototype keys before any merge operation.

# npm
npm update exceljs-hardened
 
# yarn
yarn upgrade exceljs-hardened
 
# pnpm
pnpm update exceljs-hardened

Workaround (if immediate upgrade is not possible)

If you cannot upgrade immediately, consider:

  • Validating XLSX files through a separate sandboxed process before parsing
  • Restricting XLSX upload endpoints to authenticated and trusted users only
  • Using Object.freeze(Object.prototype) at application startup (note: this may break other code)

Detection

Search your package.json and package-lock.json for exceljs-hardened:

npm list exceljs-hardened

If the version is below 5.0.0, upgrade immediately. Audit your application for XLSX parsing code paths that process cell notes.

Timeline

DateEvent
2026-08-24CVE assigned and published to NVD
2026-08-24exceljs-hardened v5.0.0 released with fix

References