diff --git a/give.php b/give.php index 2b3fb75711..2a00cb3b32 100644 --- a/give.php +++ b/give.php @@ -6,7 +6,7 @@ * Description: The most robust, flexible, and intuitive way to accept donations on WordPress. * Author: GiveWP * Author URI: https://givewp.com/ - * Version: 3.19.2 + * Version: 3.19.3 * Requires at least: 6.5 * Requires PHP: 7.2 * Text Domain: give @@ -411,7 +411,7 @@ private function setup_constants() { // Plugin version. if (!defined('GIVE_VERSION')) { - define('GIVE_VERSION', '3.19.2'); + define('GIVE_VERSION', '3.19.3'); } // Plugin Root File. diff --git a/includes/formatting.php b/includes/formatting.php index ae9a3f142b..ca8ebddd02 100644 --- a/includes/formatting.php +++ b/includes/formatting.php @@ -735,6 +735,7 @@ function give_get_cache_key($action, $query_args) * Clean variables using sanitize_text_field. Arrays are cleaned recursively. * Non-scalar values are ignored. * + * @since 3.19.3 Don't unserialize data by default and return an empty string when data is serialized and $allow_serialized_data is false * @since 3.17.2 Safe unserialize data by default * @since 1.8 * @@ -748,8 +749,8 @@ function give_clean($var, $allow_serialized_data = false) return array_map('give_clean', $var); } - if ( ! $allow_serialized_data) { - $var = Utils::safeUnserialize($var); + if ( Utils::isSerialized($var)) { + $var = $allow_serialized_data ? Utils::safeUnserialize($var) : ''; } return is_scalar($var) ? sanitize_text_field(wp_unslash($var)) : $var; diff --git a/readme.txt b/readme.txt index a1617c9973..187399efcb 100644 --- a/readme.txt +++ b/readme.txt @@ -5,7 +5,7 @@ Tags: donation, donate, recurring donations, fundraising, crowdfunding Requires at least: 6.5 Tested up to: 6.7 Requires PHP: 7.2 -Stable tag: 3.19.2 +Stable tag: 3.19.3 License: GPLv3 License URI: http://www.gnu.org/licenses/gpl-3.0.html @@ -266,6 +266,9 @@ You can report security bugs through the Patchstack Vulnerability Disclosure Pro 10. Use almost any payment gateway integration with GiveWP through our add-ons or by creating your own add-on. == Changelog == += 3.19.3: December 24th, 2024 = +* Security: Added additional sanitization to the donation form request to prevent malicious serialized data (CVE-2024-12877) + = 3.19.2: December 17th, 2024 = * Fix: Resolved an issue with the custom donation amount field where using certain languages like Swedish were resulting in additional zero values being added diff --git a/src/Helpers/Utils.php b/src/Helpers/Utils.php index b2c46fe9a2..15412d474a 100644 --- a/src/Helpers/Utils.php +++ b/src/Helpers/Utils.php @@ -130,9 +130,9 @@ public static function removeBackslashes($data) } /** - * The regular expression attempts to capture the basic structure of a serialized array - * or object. This is more robust than the is_serialized() function but still not perfect. + * The regular expression attempts to capture the basic structure of all data types that can be serialized by PHP. * + * @since 3.19.3 Support all types of serialized data instead of only objects and arrays * @since 3.17.2 */ public static function containsSerializedDataRegex($data): bool @@ -141,7 +141,15 @@ public static function containsSerializedDataRegex($data): bool return false; } - $pattern = '/(a:\d+:\{.*\})|(O:\d+:"[^"]+":\{.*\})/'; + $pattern = '/ + (a:\d+:\{.*\}) | # Matches arrays (e.g: a:2:{i:0;s:5:"hello";i:1;i:42;}) + (O:\d+:"[^"]+":\{.*\}) | # Matches objects (e.g: O:8:"stdClass":1:{s:4:"name";s:5:"James";}) + (s:\d+:"[^"]*";) | # Matches strings (e.g: s:5:"hello";) + (i:\d+;) | # Matches integers (e.g: i:42;) + (b:[01];) | # Matches booleans (e.g: b:1; or b:0;) + (d:\d+(\.\d+)?;) | # Matches floats (e.g: d:3.14;) + (N;) # Matches NULL (e.g: N;) + /x'; return preg_match($pattern, $data) === 1; } diff --git a/tests/Unit/Helpers/UtilsTest.php b/tests/Unit/Helpers/UtilsTest.php index d0fbe9cc54..68277d1ba5 100644 --- a/tests/Unit/Helpers/UtilsTest.php +++ b/tests/Unit/Helpers/UtilsTest.php @@ -82,6 +82,7 @@ public function testMaybeSafeUnserialize($data, bool $expected) } /** + * @since 3.19.3 Test all types of serialized data * @since 3.17.2 */ public function serializedDataProvider(): array @@ -90,15 +91,18 @@ public function serializedDataProvider(): array [serialize('bar'), true], ['\\' . serialize('backslash-bypass'), true], ['\\\\' . serialize('double-backslash-bypass'), true], - [ - // String with serialized data hidden in the middle of the content - 'Lorem ipsum dolor sit amet, {a:2:{i:0;s:5:\"hello\";i:1;s:5:\"world\";}} consectetur adipiscing elit.', - true, - ], ['foo', false], [serialize('qux'), true], ['bar', false], ['foo bar', false], + // Strings with serialized data hidden in the middle of the content + ['Lorem ipsum a:2:{i:0;s:5:"hello";i:1;i:42;} dolor sit amet', true], // array + ['Lorem ipsum O:8:"stdClass":1:{s:4:"name";s:5:"James";} dolor sit amet', true], // object + ['Lorem ipsum s:5:"hello"; dolor sit amet', true], // string + ['Lorem ipsum i:42; dolor sit amet', true], // integer + ['Lorem ipsum b:1; dolor sit amet', true], // boolean + ['Lorem ipsum d:3.14; dolor sit amet', true], // float + ['Lorem ipsum N; dolor sit amet', true], // NULL ]; } }