REPORT / 01

Analysis Report · Folder Analysis cache/live-composer-page-builder_2.0.2 → cache/live-composer-page-builder_2.0.3 — CVE-2025-14071

Shared security patch analysis results

mode patchdiff ai claude_cli haiku
02 · Lifecycle actions cancel · resume · skip · regenerate
03 · Share this analysis copy link · embed report
03 · CVE Security Analysis & Writeups ai-generated · per cve

Comprehensive security analysis generated by AI for each confirmed CVE match. Click on a CVE to view the detailed writeup including vulnerability background, technical details, patch analysis, and PoC guide.

CVE-2025-14071 NVD
AI-Generated Analysis
05 · Findings filter · search · paginate
Use quotes for exact: "SQL injection" · Operators: hello AND bye, admin OR root, -error, NOT warning
Showing 0 to 0 of 0 results
modules/posts/module.php AI: 1 vulnerabilities 1 true positive CVE-2025-14071
--- cache/live-composer-page-builder_2.0.2/modules/posts/module.php	2025-12-22 00:31:03.128954565 +0000+++ cache/live-composer-page-builder_2.0.3/modules/posts/module.php	2025-12-22 00:31:07.109200904 +0000@@ -5612,23 +5612,54 @@ 		// # code... 		// } 		$dslc_options = apply_filters( 'dslc_module_options_before_output', $options );-		echo '[dslc_module_posts_output]' . serialize( $dslc_options ) . '[/dslc_module_posts_output]';+		echo '[dslc_module_posts_output]' . json_encode( $dslc_options ) . '[/dslc_module_posts_output]'; 	} }  function dslc_module_posts_output( $atts, $content = null ) { -	// Uncode module options passed as serialized content.-	$data = @unserialize( $content );+	// 1. Try JSON DECODING (New, secure format)+    $options = json_decode( $content, true ); -	if ( $data !== false ) {-		$options = unserialize( $content );-	} else {-		$fixed_data = preg_replace_callback( '!s:(\d+):"(.*?)";!', function( $match ) {-			return ( $match[1] == strlen( $match[2] ) ) ? $match[0] : 's:' . strlen( $match[2] ) . ':"' . $match[2] . '";';-		}, $content );-		$options = unserialize( $fixed_data );-	}+    // 2. Fallback to PHP unserialize if JSON fails+    // This handles all existing content saved in the serialized format.+    if ( ! is_array( $options ) ) {++        // Define the secure unserialize arguments based on PHP version.+        $unserialize_args = ( version_compare( PHP_VERSION, '7.0.0', '>=' ) )+            ? array( 'allowed_classes' => false ) // Secure on PHP 7.0++            : null; // Allows object injection on older PHP, but this is the necessary trade-off for legacy data loading.+                    // For maximum security, you should deprecate support for PHP < 7.0.++        // Try standard unserialize with object injection blocked+        $options = @unserialize( $content, $unserialize_args );++        // Fallback for broken serialization string length (from original code)+        if ( $options === false ) {+            $fixed_data = preg_replace_callback( '!s:(\d+):"(.*?)";!', function( $match ) {+                return ( $match[1] == strlen( $match[2] ) ) ? $match[0] : 's:' . strlen( $match[2] ) . ':"' . $match[2] . '";';+            }, $content );+            // Try to unserialize the fixed string, still blocking objects+            $options = @unserialize( $fixed_data, $unserialize_args );+        }+    }++    // 3. Final Validation+    if ( ! is_array( $options ) ) {+        // Data is invalid or failed to deserialize securely.+        return '';+    }+    +    // Optional: Validate that required keys exist (as suggested in the third developer solution)+    $required_keys = array( 'post_type', 'amount', 'pagination_type' );+    foreach ( $required_keys as $key ) {+        if ( ! isset( $options[ $key ] ) ) {+            return '';+        }+    }+    +    // Use the now-validated $options array for the rest of the module logic+    $opts = $options;  	ob_start(); 
AI Analysis
Vulnerability Existed: yes
TRUE POSITIVE
Insecure Deserialization - CWE-502 - modules/posts/module.php - Lines 5620-5625 (Old Code)

Old Code:
```php
// Uncode module options passed as serialized content.
$data = @unserialize( $content );

if ( $data !== false ) {
    $options = unserialize( $content );
} else {
    $fixed_data = preg_replace_callback( '!s:(\d+):"(.*?)";!', function( $match ) {
        return ( $match[1] == strlen( $match[2] ) ) ? $match[0] : 's:' . strlen( $match[2] ) . ':"' . $match[2] . '";';
    }, $content );
    $options = unserialize( $fixed_data );
}
```

Fixed Code:
```php
// 1. Try JSON DECODING (New, secure format)
$options = json_decode( $content, true );

// 2. Fallback to PHP unserialize if JSON fails
// This handles all existing content saved in the serialized format.
if ( ! is_array( $options ) ) {

    // Define the secure unserialize arguments based on PHP version.
    $unserialize_args = ( version_compare( PHP_VERSION, '7.0.0', '>=' ) )
        ? array( 'allowed_classes' => false ) // Secure on PHP 7.0+
        : null; // Allows object injection on older PHP, but this is the necessary trade-off for legacy data loading.
                // For maximum security, you should deprecate support for PHP < 7.0.

    // Try standard unserialize with object injection blocked
    $options = @unserialize( $content, $unserialize_args );

    // Fallback for broken serialization string length (from original code)
    if ( $options === false ) {
        $fixed_data = preg_replace_callback( '!s:(\d+):"(.*?)";!', function( $match ) {
            return ( $match[1] == strlen( $match[2] ) ) ? $match[0] : 's:' . strlen( $match[2] ) . ':"' . $match[2] . '";';
        }, $content );
        // Try to unserialize the fixed string, still blocking objects
        $options = @unserialize( $fixed_data, $unserialize_args );
    }
}

// 3. Final Validation
if ( ! is_array( $options ) ) {
    // Data is invalid or failed to deserialize securely.
    return '';
}

// Optional: Validate that required keys exist (as suggested in the third developer solution)
$required_keys = array( 'post_type', 'amount', 'pagination_type' );
foreach ( $required_keys as $key ) {
    if ( ! isset( $options[ $key ] ) ) {
        return '';
    }
}

// Use the now-validated $options array for the rest of the module logic
$opts = $options;
```

Explanation:
The original code used PHP's `unserialize()` function without any security restrictions, which is vulnerable to PHP Object Injection attacks (CWE-502). An attacker could craft malicious serialized data containing gadget chains to execute arbitrary code on the server. The fix addresses this in multiple ways:

1. **Primary Fix - JSON Encoding**: The module now uses `json_encode()` instead of `serialize()` for new data (line 5615), which is inherently safer as JSON cannot execute arbitrary PHP objects.

2. **Secure Deserialization**: When falling back to `unserialize()` for legacy data, the fix now uses the `allowed_classes` parameter (PHP 7.0+) set to `false`, which prevents object instantiation during unserialization, eliminating object injection vectors.

3. **Input Validation**: Additional validation checks ensure the deserialized data is an array and contains required keys before use, preventing use of corrupted or malicious data.

4. **Explicit Failure Handling**: The code now explicitly returns an empty string if deserialization fails or produces invalid data, rather than proceeding with potentially dangerous data.

This is a proper fix for insecure deserialization that maintains backward compatibility with legacy serialized data while securing the codebase for new data going forward.
CVE Analysis Results:
CVE-2025-14071: Yes
View CVE Description
The Live Composer – Free WordPress Website Builder plugin for WordPress is vulnerable to PHP Object Injection in all versions up to, and including, 2.0.2 via deserialization of untrusted input in the dslc_module_posts_output shortcode. This makes it possible for authenticated attackers, with Contributor-level access and above, to inject a PHP Object. No known POP chain is present in the vulnerable plugin, which means this vulnerability has no impact unless another plugin or theme containing a POP chain is installed on the site. If a POP chain is present via an additional plugin or theme installed on the target system, it may allow the attacker to perform actions like delete arbitrary files, retrieve sensitive data, or execute code depending on the POP chain present.
Showing 1 to 1 of 1 results