Critical

YesWiki Vulnerable to Authenticated PHP Object Injection in BazarImportAction via unserialize

  • Disclosed: 09.07.2026
  • Updated: 11.10.2026 10:22

Details

Sink

tools/bazar/services/CSVManager.php line 372-399:

php
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:

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

  1. The action is registered as bazarimport. The default BazaR page (setup/sql/default-content.sql -> BazaR page entry, ships with {{bazar showexportbuttons="1"}}) routes ?BazaR&vue=importer&id_typeannonce=<N> to BazarAction::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.

  2. BazarImportAction::run() calls $this->checkSecuredACL() with the default $adminOnly=true. Only wiki admins (or accounts the admin has added to the bazarimport action ACL) can execute it.

  3. 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('main', 'POST', 'confirmDeleteToken') for destructive operations. The import path skips the same protection.

  4. 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:

bash
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

  1. tools/bazar/services/CSVManager.php::importEntry -- pass ['allowed_classes' => 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.
  2. tools/bazar/actions/BazarImportAction.php -- add a CsrfTokenController::checkToken('main', 'POST', 'csrf-token', false) guard for the 'importentries' mode (and any other state-changing modes). The existing tools/bazar/controllers/FormController.php pattern can be lifted directly.

Affected software

Click a technology to see all vulnerabilities affecting it.

PlatformPackageVulnerable versionsFixed in
Composer package yeswiki/yeswiki < 4.6.6 4.6.6

References

CVSS score -
CVSS vector
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
Weakness (CWE)
CWE-352, CWE-502
Platform
Composer
Package
yeswiki/yeswiki
Disclosed
09.07.2026
Updated
11.10.2026 10:22

Sources and licenses

OSV / GitHub Advisory Database - GHSA-9369-69wj-7m2f - CC BY 4.0

Vulnerability history: yeswiki/yeswiki

All published vulnerabilities of this package (Composer package), newest first. Shows whether this is a one-off slip or a package that needs watching.

All (31) in the archive
Total entries
31
First → latest
03.2022 07.2026
Without a fix
2
Exploited in attacks
0

Severity breakdown

  • Critical 5
  • High 16
  • Medium 8
  • Low 2

Disclosures per year

  1. 2022: 1
  2. 2023: 0
  3. 2024: 1
  4. 2025: 12
  5. 2026: 17
Severity:
  1. YesWiki Vulnerable to Authenticated PHP Object Injection in BazarImportAction via unserialize this entry
    Critical CVE-2026-52777 < 4.6.6 4.6.6
  2. High · 8.8 CVE-2026-52775 < 4.6.6 4.6.6
  3. Critical · 9.8 CVE-2026-46670 < 4.6.4 4.6.4
  4. Critical · 10.0 CVE-2025-46348 < 4.5.4 4.5.4
  5. High · 7.1 CVE-2025-24019 < 4.5.0 4.5.0
  6. High · 7.6 CVE-2025-24018 < 4.5.0 4.5.0
  7. High · 7.6 CVE-2025-24017 < 4.5.0 4.5.0
  8. High · 9.9 CVE-2024-51478 < 4.4.5 4.4.5
  9. High · 7.5 CVE-2021-43091 < 4.1.0 4.1.0

Know which vulnerabilities affect your application

With the DockRay integration and software inventory enabled, DockRay checks reported component versions against known vulnerabilities and notifies you about confirmed matches. Coverage depends on the supported technology and available advisory data.

Connect your application
DockRay newsletter

Application security in your inbox

Important vulnerabilities, actionable guidance and practical advice for your applications. Choose your technologies and follow what matters to your project.

  • A daily digest of new vulnerabilities, critical ones included.
  • Notifications about important updates.
  • Practical advice on application security and monitoring.

Leave empty to receive updates for every technology.

Free to subscribe. Unsubscribe with one click in any email.