Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions inc/duplication/data.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?php

Check warning on line 1 in inc/duplication/data.php

View workflow job for this annotation

GitHub Actions / Code Quality Checks

Missing file doc comment

Check warning on line 1 in inc/duplication/data.php

View workflow job for this annotation

GitHub Actions / Code Quality Checks

Class file names should be based on the class name with "class-" prepended. Expected class-mucd-data.php, but found data.php.

use Psr\Log\LogLevel;

Expand Down Expand Up @@ -28,7 +28,7 @@

// Copy
$saved_options = self::db_copy_tables($from_site_id, $to_site_id);
$blog_meta = self::db_copy_blog_meta($from_site_id, $to_site_id);

Check warning on line 31 in inc/duplication/data.php

View workflow job for this annotation

GitHub Actions / Code Quality Checks

Result of static method MUCD_Data::db_copy_blog_meta() (void) is used.
// Update
self::db_update_data($from_site_id, $to_site_id, $saved_options);
}
Expand Down Expand Up @@ -306,10 +306,10 @@
global $wpdb;

$row = $wpdb->get_row( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
"SHOW KEYS FROM `{$table}` WHERE Key_name = 'PRIMARY'" // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared

Check warning on line 309 in inc/duplication/data.php

View workflow job for this annotation

GitHub Actions / Code Quality Checks

Use placeholders and $wpdb->prepare(); found interpolated variable {$table} at "SHOW KEYS FROM `{$table}` WHERE Key_name = 'PRIMARY'"
);

$cache[ $table ] = $row ? $row->Column_name : null;

Check warning on line 312 in inc/duplication/data.php

View workflow job for this annotation

GitHub Actions / Code Quality Checks

Object property "$Column_name" is not in valid snake_case format, try "$column_name"

return $cache[ $table ];
}
Expand Down Expand Up @@ -450,7 +450,7 @@
if (is_serialized($row[ $field ])) {
$double_serialize = false;
$original_value = $row[ $field ];
$row[ $field ] = @unserialize($row[ $field ]);
$row[ $field ] = @unserialize($row[ $field ], ['allowed_classes' => false]);

Check warning on line 453 in inc/duplication/data.php

View workflow job for this annotation

GitHub Actions / Code Quality Checks

unserialize() found. Serialized data has known vulnerability problems with Object Injection. JSON is generally a better approach for serializing data. See https://www.owasp.org/index.php/PHP_Object_Injection

Check warning on line 453 in inc/duplication/data.php

View workflow job for this annotation

GitHub Actions / Code Quality Checks

Silencing errors is strongly discouraged. Use proper error checking instead. Found: @unserialize($row[ ...

// Safety: if unserialize failed, return the original value
// instead of re-serializing false — which would destroy the data.
Expand All @@ -460,7 +460,7 @@

// FOR SERIALISED OPTIONS, like in wp_carousel plugin
if (is_serialized($row[ $field ])) {
$inner_unserialized = @unserialize($row[ $field ]);
$inner_unserialized = @unserialize($row[ $field ], ['allowed_classes' => false]);

Check warning on line 463 in inc/duplication/data.php

View workflow job for this annotation

GitHub Actions / Code Quality Checks

unserialize() found. Serialized data has known vulnerability problems with Object Injection. JSON is generally a better approach for serializing data. See https://www.owasp.org/index.php/PHP_Object_Injection

Check warning on line 463 in inc/duplication/data.php

View workflow job for this annotation

GitHub Actions / Code Quality Checks

Silencing errors is strongly discouraged. Use proper error checking instead. Found: @unserialize($row[ ...

if (false === $inner_unserialized && 'b:0;' !== $row[ $field ]) {
// Inner unserialize failed — fall back to single-serialized handling.
Expand All @@ -483,7 +483,7 @@
foreach ($array_object as $key => $value) {
try {
$row[ $field ]->$key = $value;
} catch (\Throwable $exception) {

Check warning on line 486 in inc/duplication/data.php

View workflow job for this annotation

GitHub Actions / Code Quality Checks

Empty CATCH statement detected
// ...nothing
}
}
Expand All @@ -491,7 +491,7 @@
$row[ $field ] = self::replace($row[ $field ], $from_string, $to_string);
}

$row[ $field ] = serialize($row[ $field ]);

Check warning on line 494 in inc/duplication/data.php

View workflow job for this annotation

GitHub Actions / Code Quality Checks

serialize() found. Serialized data has known vulnerability problems with Object Injection. JSON is generally a better approach for serializing data. See https://www.owasp.org/index.php/PHP_Object_Injection

// Pour des options comme wp_carousel...
if ($double_serialize) {
Expand Down
25 changes: 24 additions & 1 deletion tests/WP_Ultimo/Duplication/MUCD_Data_Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -327,10 +327,33 @@ public function test_try_replace_preserves_incomplete_serialized_object() {
$this->assertStringContainsString($old_url, $result);
}

/**
* Test try_replace does not instantiate objects from known classes.
*
* Both unserialize() calls must use allowed_classes: false so that
* __wakeup() / __destruct() side-effects are never triggered, even for
* classes that happen to be available in the duplication runtime. Any
* serialized object must be returned verbatim (same as an incomplete class).
*/
public function test_try_replace_does_not_instantiate_known_class_objects() {
// stdClass is always available; without allowed_classes: false it would
// be instantiated and processed by the object-mutation branch.
$obj = new \stdClass();
$obj->url = 'https://example.com/old/page';
$serialized = serialize($obj);
$row = ['meta_value' => $serialized];

$result = \MUCD_Data::try_replace($row, 'meta_value', 'example.com/old', 'example.com/new');

// With allowed_classes: false the object becomes __PHP_Incomplete_Class
// and the guard returns the original serialized value unchanged.
$this->assertSame($serialized, $result);
}

/**
* Test try_replace with Elementor Kit-like serialized page settings.
*
* Simulates the _elementor_page_settings structure for a Kit post.

* After URL replacement, all non-URL settings must be preserved
* exactly and the result must be valid serialized data.
*/
Expand Down
Loading