Skip to content

Commit

Permalink
Merge branch 'develop' into feature/donation-summary-hook-store
Browse files Browse the repository at this point in the history
  • Loading branch information
jonwaldstein authored Jan 10, 2025
2 parents 1037fd0 + 6bbe4f0 commit e6108c9
Show file tree
Hide file tree
Showing 9 changed files with 108 additions and 19 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/DonationForms/ViewModels/DonationFormViewModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ public function exports(): array
* 5. Finally, call the specific WP function wp_print_footer_scripts()
* - This will only print the footer scripts that are enqueued within our route.
*
* @unreleased Adds class for form design
* @since 3.11.0 Sanitize customCSS property
* @since 3.0.0
*/
Expand All @@ -277,7 +278,7 @@ public function render(): string
endif; ?>

<?php
$classNames = ['givewp-donation-form'];
$classNames = ['givewp-donation-form', "givewp-donation-form-design--{$this->designId()}"];

if ($this->previewMode) {
$classNames[] = 'givewp-donation-form--preview';
Expand Down
31 changes: 22 additions & 9 deletions src/DonationForms/resources/styles/components/_amount.scss
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ $borderColor: #9A9A9A;

&:focus-within {
border-color: var(--givewp-primary-color);
outline: 1px solid var(--givewp-primary-color);
}
}

Expand Down Expand Up @@ -134,6 +135,7 @@ $borderColor: #9A9A9A;
flex: 1;
gap: var(--givewp-spacing-4);
min-width: calc((100% - var(--givewp-spacing-2)) / 2);
outline: none;

@media screen and (min-width: variables.$givewp-breakpoint-sm) {
min-width: calc((100% - var(--givewp-spacing-2) * 2) / 3);
Expand All @@ -143,7 +145,6 @@ $borderColor: #9A9A9A;
flex-basis: 100%;
padding-bottom: var(--givewp-spacing-2);
}
;

.givewp-fields-amount__level {
&--description {
Expand Down Expand Up @@ -187,7 +188,11 @@ $borderColor: #9A9A9A;
margin-bottom: 0;
box-shadow: none;

&:hover {
&:focus {
outline: 1px solid var(--givewp-primary-color);
}

&:hover {
border-color: var(--givewp-primary-color);
}

Expand All @@ -197,8 +202,16 @@ $borderColor: #9A9A9A;

&--selected {
background-color: var(--givewp-primary-color);
border-color: var(--givewp-primary-color);
border: none;
color: #fff;

&:focus{
outline: none;
}

&:focus-visible {
outline: thick double var(--givewp-primary-color);
}
}
}

Expand Down Expand Up @@ -247,6 +260,10 @@ $borderColor: #9A9A9A;
border-radius: var(--givewp-rounded-2);
transition: background-color 100ms ease-in-out;

&:focus-within {
outline: thick double var(--givewp-primary-color);
}

&:has(> input[type="radio"]:checked) {
background-color: var(--givewp-primary-color);

Expand All @@ -264,12 +281,8 @@ $borderColor: #9A9A9A;
}

input[type="radio"] {
display: none;

&:focus {
box-shadow: none;
outline: none;
}
position: absolute;
z-index: -999;
}
}
}
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 e6108c9

Please sign in to comment.