From 410222458403a31ee3883ba370db0f9ddf580efd Mon Sep 17 00:00:00 2001 From: "InstaWP Engineer (bot)" Date: Thu, 24 Sep 2026 08:42:36 +0000 Subject: [PATCH 1/5] Security: do not instantiate objects when validating serialized SQL data `Serialized_Data::run()` validates whether a value being saved from the database editor is well-formed serialized PHP. It only needs the shape of the data, never the objects it describes, but it called `unserialize()` with no `allowed_classes` restriction, so validating a row would construct whatever classes the value named. Pass `allowed_classes => false`. Objects then decode to `__PHP_Incomplete_Class`, which is not `false`, so the existing validity test is unchanged for legitimate data -- verified across 18 inputs (valid scalars, arrays, objects, nested objects, enums, `b:0;`, and three malformed payloads): every save/block verdict is identical to 2.6.7, and the only behavioural difference is that no constructor, `__wakeup()` or `__destruct()` runs. This completes the sweep started in 2.6.7, which hardened `recursive_unserialize_replace()` but missed this call site. Reported by Raphael P. Cigana via WPScan. Co-Authored-By: Claude Opus 4.8 --- docs/changelog.txt | 3 +++ docs/readme.txt | 5 ++++- .../Extension/SQL/Tests/class-serialized-data.php | 12 +++++++++++- string-locator.php | 2 +- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index c8034d5..5196f1f 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -1,3 +1,6 @@ += 2.6.8 (2026-09-24) = +* Security: hardened serialized data validation in the database editor so that objects in the data being checked are never instantiated. Reported by Raphael P. Cigana via WPScan. + = 2.6.7 (2025-01-15) = * Fixed secured unserialized data handling to prevent potential vulnerabilities. * Verified compatibility with WordPress 6.7 diff --git a/docs/readme.txt b/docs/readme.txt index 9073165..53fa133 100644 --- a/docs/readme.txt +++ b/docs/readme.txt @@ -5,7 +5,7 @@ Plugin URI: http://wordpress.org/plugins/string-locator/ Tags: text, search, find, syntax, highlight Requires at least: 4.9 Tested up to: 6.7 -Stable tag: 2.6.7 +Stable tag: 2.6.8 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html @@ -46,6 +46,9 @@ When writing your search string, make sure to wrap your search in forward slashe == Changelog == += 2.6.8 (2026-09-24) = +* Security: hardened serialized data validation in the database editor so that objects in the data being checked are never instantiated. Reported by Raphael P. Cigana via WPScan. + = 2.6.7 (2025-01-15) = * Fixed secured unserialized data handling to prevent potential vulnerabilities. * Verified compatibility with WordPress 6.7 diff --git a/includes/Extension/SQL/Tests/class-serialized-data.php b/includes/Extension/SQL/Tests/class-serialized-data.php index 4b2c5b5..6fc15ca 100644 --- a/includes/Extension/SQL/Tests/class-serialized-data.php +++ b/includes/Extension/SQL/Tests/class-serialized-data.php @@ -118,7 +118,17 @@ public function run( $content ) { $this->errors = array(); if ( \is_serialized( $this->content ) ) { - $test_data = @unserialize( $this->content ); + /* + * This check only needs to know whether the value is well-formed + * serialized PHP; it never needs the objects that value describes, and + * the value itself is row content that the site owner did not + * necessarily author. `allowed_classes => false` therefore keeps any + * object in it from being instantiated during validation. + * + * Objects still decode to `__PHP_Incomplete_Class`, which is not + * `false`, so the validity test below is unchanged for legitimate data. + */ + $test_data = @unserialize( $this->content, array( 'allowed_classes' => false ) ); if ( 'b:0;' !== $this->content && false === $test_data ) { $this->errors[] = array( diff --git a/string-locator.php b/string-locator.php index 2a0d2e3..b818e09 100644 --- a/string-locator.php +++ b/string-locator.php @@ -3,7 +3,7 @@ * Plugin Name: String Locator * Plugin URI: https://wordpress.org/plugins/string-locator/ * Description: Scan through theme and plugin files looking for text strings - * Version: 2.6.7 + * Version: 2.6.8 * Author: InstaWP * Author URI: https://instawp.com/ * Text Domain: string-locator From 734c9d097a9b363f88a451aace57c25c097b6272 Mon Sep 17 00:00:00 2001 From: "InstaWP Engineer (bot)" Date: Thu, 24 Sep 2026 08:55:25 +0000 Subject: [PATCH 2/5] Review round 1: correct the enum caveat, add wp.org Upgrade Notice Two review findings, neither affecting behaviour: - `allowed_classes => false` does NOT gate PHP 8.1 enums: an `E:` value still resolves to the real case, and WP's `is_serialized()` accepts that token. Measured, and confirmed harmless -- an enum may not declare __wakeup/__destruct/__construct/__serialize/__unserialize, so it cannot carry a gadget. The comment said the gate was total; it now names the exception so the next reader does not reason from a false guarantee. - Added an `== Upgrade Notice ==` section, which wp.org surfaces in the update nag. Worth having on a security release. Token stream of the PHP file is unchanged (307 tokens before and after), so the code edit is comment-only. All 31 harness verdicts still identical to 2.6.7; php -l and PHPCS clean. Co-Authored-By: Claude Opus 4.8 --- docs/readme.txt | 5 +++++ includes/Extension/SQL/Tests/class-serialized-data.php | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/docs/readme.txt b/docs/readme.txt index 53fa133..6a0ae44 100644 --- a/docs/readme.txt +++ b/docs/readme.txt @@ -44,6 +44,11 @@ When writing your search string, make sure to wrap your search in forward slashe 3. Having clicked the link for one of the results and being taken to the editor in the browser. 4. Smart-Scan has detected an inconsistency in the use of braces. +== Upgrade Notice == + += 2.6.8 = +Security release. Updating is recommended for all sites. + == Changelog == = 2.6.8 (2026-09-24) = diff --git a/includes/Extension/SQL/Tests/class-serialized-data.php b/includes/Extension/SQL/Tests/class-serialized-data.php index 6fc15ca..b2daf3b 100644 --- a/includes/Extension/SQL/Tests/class-serialized-data.php +++ b/includes/Extension/SQL/Tests/class-serialized-data.php @@ -127,6 +127,11 @@ public function run( $content ) { * * Objects still decode to `__PHP_Incomplete_Class`, which is not * `false`, so the validity test below is unchanged for legitimate data. + * + * Enum cases are the one thing PHP does not gate here -- an `E:` value + * still resolves to the real case. That is safe: an enum may not declare + * `__wakeup()`, `__destruct()`, `__construct()`, `__serialize()` or + * `__unserialize()`, so it cannot carry a gadget. */ $test_data = @unserialize( $this->content, array( 'allowed_classes' => false ) ); From 59aee55a71abe9218ba0e3e8817820ccb74b7295 Mon Sep 17 00:00:00 2001 From: "InstaWP Engineer (bot)" Date: Thu, 24 Sep 2026 10:17:44 +0000 Subject: [PATCH 3/5] fix: declare Requires PHP: 7.0 floor, update Tested up to 7.1 unserialize()'s allowed_classes argument (added in this PR for the security fix) needs PHP 7.0+; on PHP 5.6 the call errors and run() treats that as invalid data, so the database editor would refuse to save any legitimately-serialized row. Measured 3/3 save->block flip on PHP 5.6.40, 0/16 on 7.4/8.2/8.3. Nothing previously declared a PHP floor, so wp.org would still offer this update to a PHP-5.6 site. Also updates readme Tested up to to 7.1, the WordPress version QA verified this release against. QA finding on PR #406. Co-Authored-By: Claude Opus 4.8 --- docs/readme.txt | 3 ++- string-locator.php | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/readme.txt b/docs/readme.txt index 6a0ae44..5a50020 100644 --- a/docs/readme.txt +++ b/docs/readme.txt @@ -4,7 +4,8 @@ Author URI: https://instawp.com/?utm_source=sl_plugin_author Plugin URI: http://wordpress.org/plugins/string-locator/ Tags: text, search, find, syntax, highlight Requires at least: 4.9 -Tested up to: 6.7 +Requires PHP: 7.0 +Tested up to: 7.1 Stable tag: 2.6.8 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html diff --git a/string-locator.php b/string-locator.php index b818e09..e02a5ef 100644 --- a/string-locator.php +++ b/string-locator.php @@ -4,6 +4,7 @@ * Plugin URI: https://wordpress.org/plugins/string-locator/ * Description: Scan through theme and plugin files looking for text strings * Version: 2.6.8 + * Requires PHP: 7.0 * Author: InstaWP * Author URI: https://instawp.com/ * Text Domain: string-locator From b241af9683fdab3a7b82ca4ca50c14a737f47b55 Mon Sep 17 00:00:00 2001 From: "InstaWP Engineer (bot)" Date: Thu, 24 Sep 2026 10:25:30 +0000 Subject: [PATCH 4/5] docs: generalize + de-identify 2.6.8 changelog entry Owner instruction: keep the public changelog generic (no mechanism details) and drop the reporter credit line from the public entry. Co-Authored-By: Claude Opus 4.8 --- docs/changelog.txt | 2 +- docs/readme.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index 5196f1f..7289371 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -1,5 +1,5 @@ = 2.6.8 (2026-09-24) = -* Security: hardened serialized data validation in the database editor so that objects in the data being checked are never instantiated. Reported by Raphael P. Cigana via WPScan. +* Security: hardened serialized data processing. = 2.6.7 (2025-01-15) = * Fixed secured unserialized data handling to prevent potential vulnerabilities. diff --git a/docs/readme.txt b/docs/readme.txt index 5a50020..6871768 100644 --- a/docs/readme.txt +++ b/docs/readme.txt @@ -53,7 +53,7 @@ Security release. Updating is recommended for all sites. == Changelog == = 2.6.8 (2026-09-24) = -* Security: hardened serialized data validation in the database editor so that objects in the data being checked are never instantiated. Reported by Raphael P. Cigana via WPScan. +* Security: hardened serialized data processing. = 2.6.7 (2025-01-15) = * Fixed secured unserialized data handling to prevent potential vulnerabilities. From 775c536d7b257f59fdbfe3dfd8d220963c066f00 Mon Sep 17 00:00:00 2001 From: "InstaWP Engineer (bot)" Date: Thu, 24 Sep 2026 10:27:36 +0000 Subject: [PATCH 5/5] docs: drop the Upgrade Notice section from readme.txt Owner instruction. It only existed to carry the removed 'Security release' line. Co-Authored-By: Claude Opus 4.8 --- docs/readme.txt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/docs/readme.txt b/docs/readme.txt index 6871768..77e519a 100644 --- a/docs/readme.txt +++ b/docs/readme.txt @@ -45,11 +45,6 @@ When writing your search string, make sure to wrap your search in forward slashe 3. Having clicked the link for one of the results and being taken to the editor in the browser. 4. Smart-Scan has detected an inconsistency in the use of braces. -== Upgrade Notice == - -= 2.6.8 = -Security release. Updating is recommended for all sites. - == Changelog == = 2.6.8 (2026-09-24) =