Skip to content

Commit

Permalink
Merge branch 'develop' into fix/missing-date-timezone-GIVE-1233
Browse files Browse the repository at this point in the history
  • Loading branch information
glaubersilva authored Jan 9, 2025
2 parents 1cb137d + 5c03e2b commit 285b9c7
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 9 deletions.
4 changes: 2 additions & 2 deletions give.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.3
* Version: 3.19.4
* Requires at least: 6.5
* Requires PHP: 7.2
* Text Domain: give
Expand Down Expand Up @@ -411,7 +411,7 @@ private function setup_constants()
{
// Plugin version.
if (!defined('GIVE_VERSION')) {
define('GIVE_VERSION', '3.19.3');
define('GIVE_VERSION', '3.19.4');
}

// Plugin Root File.
Expand Down
6 changes: 5 additions & 1 deletion readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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.3
Stable tag: 3.19.4
License: GPLv3
License URI: http://www.gnu.org/licenses/gpl-3.0.html

Expand Down Expand Up @@ -266,6 +266,10 @@ 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.4: January 7th, 2025 =
* Security: Added additional sanitization to the donation form request to prevent malicious encoded data
* Security: Added additional validation to the company field

= 3.19.3: December 24th, 2024 =
* Security: Added additional sanitization to the donation form request to prevent malicious serialized data (CVE-2024-12877)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ protected function convertInnerBlockToNode(BlockModel $block, int $blockIndex)
}

/**
* @since 3.19.4 add max rule to company field
* @since 3.9.0 Add "givewp/donor-phone" block
* @since 3.0.0
*
Expand Down Expand Up @@ -192,7 +193,7 @@ protected function createNodeFromBlockWithUniqueAttributes(BlockModel $block, in
return DonationSummary::make('donation-summary');

case "givewp/company":
return Text::make('company');
return Text::make('company')->rules('max:255');

case "givewp/text":
return Text::make(
Expand Down
5 changes: 5 additions & 0 deletions src/DonationForms/FormPage/TemplateHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,15 @@ public function __construct( $post, string $formPageTemplatePath )
}

/**
* @unreleased Add earlier return for archive pages
* @since 3.0.0
*/
public function handle($template)
{
if (is_archive()) {
return $template;
}

return $this->isNextGenForm()
? $this->formPageTemplatePath
: $template;
Expand Down
3 changes: 2 additions & 1 deletion src/Donors/ListTable/Columns/DonorInformationColumn.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public function getLabel(): string
}

/**
* @unreleased Use email to get avatar URL
* @since 2.24.0
*
* @inheritDoc
Expand All @@ -56,7 +57,7 @@ public function getCellValue($model): string

return sprintf(
$template,
get_avatar_url($model->id, ['size' => 64]),
get_avatar_url($model->email, ['size' => 64]),
admin_url("edit.php?post_type=give_forms&page=give-donors&view=overview&id=$model->id"),
trim("$model->firstName $model->lastName"),
$model->email
Expand Down
25 changes: 23 additions & 2 deletions src/Helpers/Utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,22 @@ public static function removeBackslashes($data)
return $data;
}

/**
* Decode strings recursively to prevent double (or more) encoded strings
*
* @since 3.19.4
*/
public static function recursiveUrlDecode(string $data): string
{
$decoded = urldecode($data);

return $decoded === $data ? $data : self::recursiveUrlDecode($decoded);
}

/**
* The regular expression attempts to capture the basic structure of all data types that can be serialized by PHP.
*
* @since 3.19.4 Decode the string and remove any character not allowed in a serialized string
* @since 3.19.3 Support all types of serialized data instead of only objects and arrays
* @since 3.17.2
*/
Expand All @@ -141,9 +154,17 @@ public static function containsSerializedDataRegex($data): bool
return false;
}

$data = self::recursiveUrlDecode($data);

/**
* This regular expression removes any special character that is not:
* a Letter (a-zA-Z), number (0-9), or any of the characters {}, :, ;, ", ', ., [, ], (, ), ,
*/
$data = preg_replace('/[^a-zA-Z0-9:{};"\'.\[\](),]/', '', $data);

$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";})
(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;)
Expand Down
47 changes: 45 additions & 2 deletions tests/Unit/Helpers/UtilsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,14 @@ public function testMaybeSafeUnserialize($data, bool $expected)
}

/**
* @unreleased Test encoded strings and strings with special characters
* @since 3.19.3 Test all types of serialized data
* @since 3.17.2
*/
public function serializedDataProvider(): array
{
return [
[serialize('bar'), true],
['\\' . serialize('backslash-bypass'), true],
['\\\\' . serialize('double-backslash-bypass'), true],
['foo', false],
[serialize('qux'), true],
['bar', false],
Expand All @@ -103,6 +102,50 @@ public function serializedDataProvider(): array
['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
// Strings with special characters (e.g: emojis, spaces, control characters) that are not part of a predefined set of safe characters for serialized data structures (used to try to bypass the validations)
[
// emojis bypass sample
'O😼:8:"stdClass":1:{s😼:4:"name";s😼:5:"James";}',
true,
],
[
// spaces bypass sample
'O :8:"stdClass":1:{s :4:"name";s :5:"James";}',
true,
],
// Bypass with simple methods
[
// backslash
'\\' . serialize('backslash-bypass'),
true,
],
[
// double-backslash
'\\\\' . serialize('double-backslash-bypass'),
true,
],
// Bypass with encoding string method - URL-encoded
[
// Single encode for O:8:"stdClass":1:{s:4:"name";s:5:"James";}
'O%3A8%3A%22stdClass%22%3A1%3A%7Bs%3A4%3A%22name%22%3Bs%3A5%3A%22James%22%3B%7D',
true,
],
[
// Double encode for O:8:"stdClass":1:{s:4:"name";s:5:"James";}
'O%253A8%253A%2522stdClass%2522%253A1%253A%257Bs%253A4%253A%2522name%2522%253Bs%253A5%253A%2522James%2522%253B%257D',
true,
],
// Samples using multiple obfuscation techniques together
[
// Single URL-encoded for O😼:8:"stdClass":1:{s😼:4:"name";s😼:5:"James";}
'O%F0%9F%98%BC%3A8%3A%22stdClass%22%3A1%3A%7Bs%F0%9F%98%BC%3A4%3A%22name%22%3Bs%F0%9F%98%BC%3A5%3A%22James%22%3B%7D',
true,
],
[
// Double URL-encoded for O😼:8:"stdClass":1:{s😼:4:"name";s😼:5:"James";}
'O%25F0%259F%2598%25BC%253A8%253A%2522stdClass%2522%253A1%253A%257Bs%25F0%259F%2598%25BC%253A4%253A%2522name%2522%253Bs%25F0%259F%2598%25BC%253A5%253A%2522James%2522%253B%257D',
true,
],
];
}
}

0 comments on commit 285b9c7

Please sign in to comment.