Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2025-22131

CVE-2025-22131: PhpOffice PhpSpreadsheet XSS Vulnerability

CVE-2025-22131 is a Cross-Site Scripting vulnerability in PhpOffice PhpSpreadsheet that affects HTML conversion of XLSX files. This post covers the technical details, affected versions, security impact, and mitigation.

Published:

CVE-2025-22131 Overview

CVE-2025-22131 is a Cross-Site Scripting (XSS) vulnerability in PhpSpreadsheet, a widely used PHP library for reading and writing spreadsheet files. The flaw resides in the HTML writer component that converts XLSX files into HTML for display in web responses. An attacker can craft a spreadsheet with a malicious worksheet title. When the application renders the workbook to HTML, the unescaped title is injected into the navigation markup and executes in the victim's browser.

Critical Impact

Attackers who can supply an XLSX file to an application using PhpSpreadsheet's HTML writer can execute arbitrary JavaScript in the context of any user viewing the rendered spreadsheet.

Affected Products

  • PHPOffice PhpSpreadsheet (multiple versions prior to the patched releases)
  • PHP applications that render user-supplied XLSX files via PhpSpreadsheet\Writer\Html
  • Downstream frameworks and CMS plugins bundling vulnerable PhpSpreadsheet builds

Discovery Timeline

  • 2025-01-20 - CVE-2025-22131 published to the National Vulnerability Database
  • 2026-06-17 - Last updated in NVD database

Technical Details for CVE-2025-22131

Vulnerability Analysis

The vulnerability is a stored or reflected Cross-Site Scripting issue classified under [CWE-79]. PhpSpreadsheet's HTML writer at src/PhpSpreadsheet/Writer/Html.php builds an HTML representation of an uploaded workbook. When generating the sheet navigation list, the writer concatenates the raw output of $sheet->getTitle() directly into the HTML string without any output encoding.

An attacker who controls an XLSX file can rename a worksheet to include HTML or JavaScript payloads. When a server-side handler passes that workbook through the HTML writer and returns the result to a browser, the payload executes in the victim's session context. Impact includes session token theft, cross-site request forgery via authenticated fetches, and account takeover in single-page applications that trust the rendered output.

Root Cause

The root cause is missing output encoding when interpolating spreadsheet metadata into HTML. The sheet title is user-controlled data that flows from the XLSX archive directly into an <a> element inside the navigation <ul>. Without a call to htmlspecialchars(), characters such as <, >, and " retain their HTML significance and break out of the intended text context.

Attack Vector

Exploitation requires an attacker to deliver a crafted XLSX file to a server that renders it to HTML and returns the output to a user. This is common in document preview features, invoicing portals, and analytics dashboards. User interaction is required in the form of viewing the rendered file. No authentication or elevated privileges are required on the target application.

php
            $html .= '<ul class="navigation">' . PHP_EOL;

            foreach ($sheets as $sheet) {
-                $html .= '  <li class="sheet' . $sheetId . '"><a href="#sheet' . $sheetId . '">' . $sheet->getTitle() . '</a></li>' . PHP_EOL;
+                $html .= '  <li class="sheet' . $sheetId . '"><a href="#sheet' . $sheetId . '">' . htmlspecialchars($sheet->getTitle()) . '</a></li>' . PHP_EOL;
                ++$sheetId;
            }

The patch wraps $sheet->getTitle() in htmlspecialchars() so that HTML metacharacters in worksheet names are converted to entity references before being emitted. Source: PHPOffice/PhpSpreadsheet commit 4088381.

Detection Methods for CVE-2025-22131

Indicators of Compromise

  • XLSX uploads where worksheet titles contain HTML tags, javascript: URIs, or event-handler attributes such as onerror and onload.
  • HTTP responses from document-preview endpoints containing <ul class="navigation"> blocks with unescaped script content or malformed anchor tags.
  • Outbound requests from browsers immediately after rendering a spreadsheet, targeting attacker-controlled domains with URL parameters carrying session data.

Detection Strategies

  • Inspect uploaded XLSX archives by unzipping xl/workbook.xml and matching worksheet name attributes against a pattern for HTML metacharacters or common XSS payload keywords.
  • Add a web application firewall rule that flags rendered HTML responses containing <script, onerror=, or javascript: within navigation list items.
  • Compare deployed PhpSpreadsheet versions against the fixed releases referenced in the GHSA-79xx-vf93-p7cx advisory.

Monitoring Recommendations

  • Log all file uploads with filename, uploader identity, and worksheet titles for retroactive hunting.
  • Monitor Content Security Policy (CSP) violation reports from browsers rendering spreadsheet previews.
  • Alert on anomalous outbound requests from client sessions that recently loaded a document-preview page.

How to Mitigate CVE-2025-22131

Immediate Actions Required

  • Upgrade PhpSpreadsheet to the patched version identified in the vendor advisory across all applications and container images.
  • Audit application code that calls \PhpOffice\PhpSpreadsheet\Writer\Html and confirm output is served with a restrictive Content-Type and CSP.
  • Restrict XLSX uploads to authenticated users and validate worksheet titles against an allowlist of printable, non-HTML characters.

Patch Information

The fix is delivered in commit 4088381 and detailed in the GitHub Security Advisory GHSA-79xx-vf93-p7cx. Update via Composer using composer update phpoffice/phpspreadsheet and redeploy dependent services. Verify the installed version with composer show phpoffice/phpspreadsheet after the update.

Workarounds

  • Sanitize worksheet titles before invoking the HTML writer by calling htmlspecialchars() on $sheet->getTitle() or setting titles server-side.
  • Serve rendered spreadsheet HTML inside a sandboxed iframe with sandbox="allow-same-origin" disabled and a strict Content-Security-Policy header that blocks inline scripts.
  • Convert XLSX files to PDF or static images for preview instead of HTML when user-controlled workbook metadata cannot be trusted.
bash
# Update PhpSpreadsheet to the fixed release
composer require phpoffice/phpspreadsheet --update-with-dependencies
composer show phpoffice/phpspreadsheet | grep versions

# Recommended response header when serving rendered HTML
# Content-Security-Policy: default-src 'none'; style-src 'self'; img-src 'self' data:

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.