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

Goal: 1000 CNY · Raised: 1000 CNY

100.0%

CVE-2025-22131 PoC — PhpSpreadsheet 跨站脚本漏洞

Source
Associated Vulnerability
Title:PhpSpreadsheet 跨站脚本漏洞 (CVE-2025-22131)
Description:PhpSpreadsheet是PHPOffice开源的一款用于读取和写入电子表格文件的PHP库。 PhpSpreadsheet存在跨站脚本漏洞.攻击者利用该漏洞可以执行跨站点脚本攻击。
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

[4.0K] /data/pocs/ec54c4dfbe67b2643cb45af3fac8c85b93ff259b ├── [ 561] gen.sh ├── [6.4K] poc.xlsx └── [2.3K] README.md 0 directories, 3 files
Shenlong Bot has cached this for you
Remarks
    1. It is advised to access via the original source first.
    2. If the original source is unavailable, please email f.jinxu#gmail.com for a local snapshot (replace # with @).
    3. Shenlong has snapshotted the POC code for you. To support long-term maintenance, please consider donating. Thank you for your support.