Goal Reached Thanks to every supporter — we hit 100%!

Goal: 1000 CNY · Raised: 1359 CNY

100%

CVE-2025-22131 PoC — Cross-Site Scripting (XSS) vulnerability in generateNavigation() function

Source
Associated Vulnerability
Title: Cross-Site Scripting (XSS) vulnerability in generateNavigation() function (CVE-2025-22131)
Description:PhpSpreadsheet is a PHP library for reading and writing spreadsheet files. Cross-Site Scripting (XSS) vulnerability in the code which translates the XLSX file into a HTML representation and displays it in the response.
Description
PoC for CVE-2025-22131
Readme
# CVE-2025-22131-PoC
PoC for CVE-2025-22131 
<br> <br>
[PhpSpreadsheet](https://github.com/PHPOffice/PhpSpreadsheet) is a library written in pure PHP and offers a set of classes that allow you to read and write various spreadsheet file formats such as Excel and LibreOffice Calc. 

phpspreadsheet version `<1.29.8>=2.2.0, <2.3.6>=2.0.0, <2.1.7>=3.0.0, <3.8.0` is affected by a vulnerability where the sheet names are not properly sanitized which leads to XSS.
<br> 

## Summary
- create a simple xlsx file with more than 1 sheet and save it.
- unzip the file, update the sheet name manually to the xss payload
- zip the file once again
- upload the xlsx file to the vulnerable server
- exfiltrate the victim's cookie on the given url

  **Note:** I have used the payload to exfiltrate victim's cookie, if something else is desired, update the `xl/workbook.xml` file accordingly.

## Affected Code
```php
    /**
     * Generate sheet tabs.
     */
    public function generateNavigation(): string
    {
        // Fetch sheets
        $sheets = [];
        if ($this->sheetIndex === null) {
            $sheets = $this->spreadsheet->getAllSheets();
        } else {
            $sheets[] = $this->spreadsheet->getSheet($this->sheetIndex);
        }

        // Construct HTML
        $html = '';

        // Only if there are more than 1 sheets
        if (count($sheets) > 1) {
            // Loop all sheets
            $sheetId = 0;

            $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;
                ++$sheetId;
            }

            $html .= '</ul>' . PHP_EOL;
        }

        return $html;
    }
```
Here the `$sheet->getTitle()` is not properly escaped  using `htmlspecialchars()` which is why an attacker can inject HTML. <br>
Note that this piece of code only runs when there are more than 1 sheets, so it is necessary to have an xlsx file with more than 1 sheet. <br> 
In the PoC, an image tag is used to then exfiltrate the cookies of the victim to the attacker's url.


## References
- https://github.com/PHPOffice/PhpSpreadsheet/commit/4088381ccfaf241d7d42c333de0dc8c98e338743
- https://security.snyk.io/vuln/SNYK-PHP-PHPOFFICEPHPSPREADSHEET-8651746
File Snapshot

Log in to view the POC file snapshot cached by Shenlong Bot

Log in to view
Remarks
    1. It is advised to access via the original source first.
    2. Local POC snapshots are reserved for subscribers — if the original source is unavailable, the local mirror is part of the paid plan.
    3. Mirroring, verifying, and maintaining this POC archive takes ongoing effort, so local snapshots are a paid feature. Your subscription keeps the archive online — thank you for the support. View subscription plans →