WP Activity Log <= 5.6.3.1 - Unauthenticated PHP Object Injection
Description
The WP Activity Log plugin for WordPress is vulnerable to PHP Object Injection in versions up to, and including, 5.6.3.1 via deserialization of untrusted input. This makes it possible for unauthenticated attackers to inject a PHP Object. No known POP chain is present in the vulnerable software. If a POP chain is present via an additional plugin or theme installed on the target system, it could allow the attacker to delete arbitrary files, retrieve sensitive data, or execute code.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:HTechnical Details
<=5.6.3.1What Changed in the Fix
Changes introduced in v5.6.4
Source Code
WordPress.org SVN# Exploitation Research Plan - CVE-2026-54806 ## 1. Vulnerability Summary The **WP Activity Log** plugin (versions <= 5.6.3.1) is vulnerable to **unauthenticated PHP Object Injection**. The vulnerability exists in the way the plugin processes event metadata before storing it in the database. Specif…
Show full research plan
Exploitation Research Plan - CVE-2026-54806
1. Vulnerability Summary
The WP Activity Log plugin (versions <= 5.6.3.1) is vulnerable to unauthenticated PHP Object Injection. The vulnerability exists in the way the plugin processes event metadata before storing it in the database. Specifically, when an event is triggered, the plugin iterates through the provided metadata and calls maybe_unserialize() on any value associated with the CurrentUserRoles key.
If an attacker can trigger an event where they control the contents of the CurrentUserRoles metadata, they can inject arbitrary PHP objects. While the plugin itself may not contain a usable POP chain, the presence of other plugins or themes on the system could allow for remote code execution or file deletion.
2. Attack Vector Analysis
- Endpoint: Any public-facing URL that triggers a monitored event (e.g., a 404 error page, a REST API request, or a failed login attempt).
- Parameter:
CurrentUserRoles. - Authentication: None (Unauthenticated).
- Preconditions: The plugin must be configured to log the specific event being triggered (default settings typically log 404s and REST API requests).
The core of the attack relies on the fact that many "Sensors" in WP Activity Log capture request parameters (from $_GET, $_POST, or $_REQUEST) and include them in the metadata of the event being logged.
3.
Summary
WP Activity Log versions up to 5.6.3.1 are vulnerable to unauthenticated PHP Object Injection due to the insecure use of the maybe_unserialize() function on the 'CurrentUserRoles' metadata field. This occurs when the plugin processes and retrieves event data, allowing an attacker to inject arbitrary PHP objects into the application context via crafted request parameters that are logged by the plugin.
Vulnerable Code
// classes/Entities/class-occurrences-entity.php (around line 486) $result = $meta['value']; } $result = maybe_unserialize( $result ); if ( 'CurrentUserRoles' === $name && is_string( $result ) ) { --- // classes/Entities/class-occurrences-entity.php (around line 619) if ( isset( self::$migrated_meta[ $name ] ) ) { if ( 'CurrentUserRoles' === $name ) { $value = maybe_unserialize( $value ); if ( is_array( $value ) && ! empty( $value ) ) { $data_to_store[ self::$migrated_meta[ $name ] ] = implode( ',', $value ); --- // classes/Entities/class-occurrences-entity.php (around line 704) foreach ( self::$migrated_meta as $name => $new_name ) { $prepared_array[ $result_row[ $table_name . 'id' ] ]['meta_values'][ $name ] = \maybe_unserialize( $result_row[ $table_name . $new_name ] ); }
Security Fix
@@ -468,7 +468,8 @@ } // Check if the meta is part of the occurrences table. - if ( in_array( $name, array_keys( self::$migrated_meta ), true ) ) { + $is_migrated_meta = in_array( $name, array_keys( self::$migrated_meta ), true ); + if ( $is_migrated_meta ) { $property_name = self::$migrated_meta[ $name ]; if ( isset( $data_collected[ $property_name ] ) ) { $result = $data_collected[ $property_name ]; @@ -483,7 +484,10 @@ $result = $meta['value']; } - $result = maybe_unserialize( $result ); + if ( ! $is_migrated_meta ) { + $result = \maybe_unserialize( $result ); + } + if ( 'CurrentUserRoles' === $name && is_string( $result ) ) { $result = preg_replace( '/[\[\]"]/', '', $result ); $result = explode( ',', $result ); @@ -701,7 +708,7 @@ } foreach ( self::$migrated_meta as $name => $new_name ) { - $prepared_array[ $result_row[ $table_name . 'id' ] ]['meta_values'][ $name ] = \maybe_unserialize( $result_row[ $table_name . $new_name ] ); + $prepared_array[ $result_row[ $table_name . 'id' ] ]['meta_values'][ $name ] = $result_row[ $table_name . $new_name ]; } }
Exploit Outline
The exploit target is the automatic logging of HTTP request parameters during monitored events. 1. An unauthenticated attacker identifies an endpoint that triggers a monitored event (e.g., a 404 error page or a REST API request). 2. The attacker sends a request to this endpoint containing a parameter named `CurrentUserRoles` (or a parameter that maps to it depending on the specific sensor configuration). 3. The payload for this parameter is a serialized PHP object targeting a known POP chain available on the system (from other plugins or themes). 4. When the plugin processes the event to log it, the `Occurrences_Entity::store_record` or `Occurrences_Entity::get_meta` methods call `maybe_unserialize()` on the provided payload. 5. This triggers the object lifecycle methods (e.g., `__wakeup` or `__destruct`), resulting in remote code execution, file manipulation, or other impacts depending on the available POP chain.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.