Site Reviews - Version 5.13.1

Version Description

(2021-08-02) =

  • Fixed a possible stored XSS vulnerability which allowed an admin user to add a malicious value when editing a review from the WordPress admin.
  • Fixed the terms toggle which broke due to the multi-checkbox fix in a previous update
Download this release

Release Info

Developer geminilabs
Plugin Icon 128x128 Site Reviews
Version 5.13.1
Comparing to
See all releases

Code changes from version 5.13.0 to 5.13.1

languages/site-reviews-en_US.po CHANGED
@@ -1508,7 +1508,7 @@ msgstr ""
1508
  "The [%s] method has been deprecated and will be soon be removed, please use "
1509
  "the [%s] method instead."
1510
 
1511
- #: plugin/Review.php:334, plugin/Controllers/ListTableColumns/ColumnValueAuthorName.php:20
1512
  msgctxt "admin-text"
1513
  msgid "Unknown"
1514
  msgstr "Unknown"
1508
  "The [%s] method has been deprecated and will be soon be removed, please use "
1509
  "the [%s] method instead."
1510
 
1511
+ #: plugin/Review.php:336, plugin/Controllers/ListTableColumns/ColumnValueAuthorName.php:20
1512
  msgctxt "admin-text"
1513
  msgid "Unknown"
1514
  msgstr "Unknown"
languages/site-reviews.pot CHANGED
@@ -1077,7 +1077,7 @@ msgctxt "admin-text"
1077
  msgid "The [%s] method has been deprecated and will be soon be removed, please use the [%s] method instead."
1078
  msgstr ""
1079
 
1080
- #: plugin/Review.php:334, plugin/Controllers/ListTableColumns/ColumnValueAuthorName.php:20
1081
  msgctxt "admin-text"
1082
  msgid "Unknown"
1083
  msgstr ""
1077
  msgid "The [%s] method has been deprecated and will be soon be removed, please use the [%s] method instead."
1078
  msgstr ""
1079
 
1080
+ #: plugin/Review.php:336, plugin/Controllers/ListTableColumns/ColumnValueAuthorName.php:20
1081
  msgctxt "admin-text"
1082
  msgid "Unknown"
1083
  msgstr ""
plugin/Controllers/ReviewController.php CHANGED
@@ -21,7 +21,6 @@ use GeminiLabs\SiteReviews\Helper;
21
  use GeminiLabs\SiteReviews\Helpers\Arr;
22
  use GeminiLabs\SiteReviews\Helpers\Cast;
23
  use GeminiLabs\SiteReviews\Modules\Html\ReviewHtml;
24
- use GeminiLabs\SiteReviews\Request;
25
  use GeminiLabs\SiteReviews\Review;
26
 
27
  class ReviewController extends Controller
@@ -112,7 +111,7 @@ class ReviewController extends Controller
112
 
113
  /**
114
  * Triggered when one or more categories are added or removed from a review.
115
- *
116
  * @param int $postId
117
  * @param array $terms
118
  * @param array $newTTIds
@@ -134,7 +133,7 @@ class ReviewController extends Controller
134
 
135
  /**
136
  * Triggered when a post status changes or when a review is approved|unapproved|trashed.
137
- *
138
  * @param string $oldStatus
139
  * @param string $newStatus
140
  * @param \WP_Post $post
@@ -161,7 +160,7 @@ class ReviewController extends Controller
161
 
162
  /**
163
  * Triggered when a review's assigned post IDs are updated.
164
- *
165
  * @return void
166
  * @action site-reviews/review/updated/post_ids
167
  */
@@ -174,7 +173,7 @@ class ReviewController extends Controller
174
 
175
  /**
176
  * Triggered when a review's assigned users IDs are updated.
177
- *
178
  * @return void
179
  * @action site-reviews/review/updated/user_ids
180
  */
@@ -187,7 +186,7 @@ class ReviewController extends Controller
187
 
188
  /**
189
  * Triggered after a review is created.
190
- *
191
  * @return void
192
  * @action site-reviews/review/created
193
  */
@@ -199,7 +198,7 @@ class ReviewController extends Controller
199
 
200
  /**
201
  * Triggered when a review is created.
202
- *
203
  * @param int $postId
204
  * @return void
205
  * @action site-reviews/review/create
@@ -226,7 +225,7 @@ class ReviewController extends Controller
226
 
227
  /**
228
  * Triggered when a review or other post type is deleted and the posts table uses the MyISAM engine.
229
- *
230
  * @param int $postId
231
  * @param \WP_Post $post
232
  * @return void
@@ -252,7 +251,7 @@ class ReviewController extends Controller
252
 
253
  /**
254
  * Triggered when a review is deleted and the posts table uses the MyISAM engine.
255
- *
256
  * @param int $reviewId
257
  * @return void
258
  * @see $this->onDeletePost()
@@ -264,7 +263,7 @@ class ReviewController extends Controller
264
 
265
  /**
266
  * Triggered when a user is deleted and the users table uses the MyISAM engine.
267
- *
268
  * @param int $userId
269
  * @return void
270
  * @action deleted_user
@@ -386,8 +385,8 @@ class ReviewController extends Controller
386
  if (Arr::get($submittedValues, 'is_editing_review')) {
387
  $submittedValues['rating'] = Arr::get($submittedValues, 'rating');
388
  $submittedValues['terms'] = Arr::get($submittedValues, 'terms', 0);
389
- glsr(ReviewManager::class)->updateRating($review->ID, $submittedValues);
390
- glsr(ReviewManager::class)->updateCustom($review->ID, $submittedValues);
391
  }
392
  $review = glsr(Query::class)->review($review->ID); // get a fresh copy of the review
393
  glsr()->action('review/saved', $review, $submittedValues);
21
  use GeminiLabs\SiteReviews\Helpers\Arr;
22
  use GeminiLabs\SiteReviews\Helpers\Cast;
23
  use GeminiLabs\SiteReviews\Modules\Html\ReviewHtml;
 
24
  use GeminiLabs\SiteReviews\Review;
25
 
26
  class ReviewController extends Controller
111
 
112
  /**
113
  * Triggered when one or more categories are added or removed from a review.
114
+ *
115
  * @param int $postId
116
  * @param array $terms
117
  * @param array $newTTIds
133
 
134
  /**
135
  * Triggered when a post status changes or when a review is approved|unapproved|trashed.
136
+ *
137
  * @param string $oldStatus
138
  * @param string $newStatus
139
  * @param \WP_Post $post
160
 
161
  /**
162
  * Triggered when a review's assigned post IDs are updated.
163
+ *
164
  * @return void
165
  * @action site-reviews/review/updated/post_ids
166
  */
173
 
174
  /**
175
  * Triggered when a review's assigned users IDs are updated.
176
+ *
177
  * @return void
178
  * @action site-reviews/review/updated/user_ids
179
  */
186
 
187
  /**
188
  * Triggered after a review is created.
189
+ *
190
  * @return void
191
  * @action site-reviews/review/created
192
  */
198
 
199
  /**
200
  * Triggered when a review is created.
201
+ *
202
  * @param int $postId
203
  * @return void
204
  * @action site-reviews/review/create
225
 
226
  /**
227
  * Triggered when a review or other post type is deleted and the posts table uses the MyISAM engine.
228
+ *
229
  * @param int $postId
230
  * @param \WP_Post $post
231
  * @return void
251
 
252
  /**
253
  * Triggered when a review is deleted and the posts table uses the MyISAM engine.
254
+ *
255
  * @param int $reviewId
256
  * @return void
257
  * @see $this->onDeletePost()
263
 
264
  /**
265
  * Triggered when a user is deleted and the users table uses the MyISAM engine.
266
+ *
267
  * @param int $userId
268
  * @return void
269
  * @action deleted_user
385
  if (Arr::get($submittedValues, 'is_editing_review')) {
386
  $submittedValues['rating'] = Arr::get($submittedValues, 'rating');
387
  $submittedValues['terms'] = Arr::get($submittedValues, 'terms', 0);
388
+ glsr(ReviewManager::class)->updateRating($review->ID, $submittedValues); // values are sanitized here
389
+ glsr(ReviewManager::class)->updateCustom($review->ID, $submittedValues); // values are sanitized here
390
  }
391
  $review = glsr(Query::class)->review($review->ID); // get a fresh copy of the review
392
  glsr()->action('review/saved', $review, $submittedValues);
plugin/Database/ReviewManager.php CHANGED
@@ -295,8 +295,8 @@ class ReviewManager
295
  public function updateRating($reviewId, array $data = [])
296
  {
297
  glsr(Cache::class)->delete($reviewId, 'reviews');
298
- $defaults = glsr(RatingDefaults::class)->restrict($data);
299
- if ($data = array_intersect_key($data, $defaults)) {
300
  return glsr(Database::class)->update('ratings', $data, [
301
  'review_id' => $reviewId,
302
  ]);
@@ -330,8 +330,8 @@ class ReviewManager
330
  return 0;
331
  }
332
  glsr(Cache::class)->delete($reviewId, 'reviews');
333
- $defaults = glsr(UpdateReviewDefaults::class)->restrict($data);
334
- if ($data = array_intersect_key($data, $defaults)) {
335
  $data = array_filter([
336
  'post_content' => Arr::get($data, 'content'),
337
  'post_date' => Arr::get($data, 'date'),
295
  public function updateRating($reviewId, array $data = [])
296
  {
297
  glsr(Cache::class)->delete($reviewId, 'reviews');
298
+ $sanitized = glsr(RatingDefaults::class)->restrict($data);
299
+ if ($data = array_intersect_key($sanitized, $data)) {
300
  return glsr(Database::class)->update('ratings', $data, [
301
  'review_id' => $reviewId,
302
  ]);
330
  return 0;
331
  }
332
  glsr(Cache::class)->delete($reviewId, 'reviews');
333
+ $sanitized = glsr(UpdateReviewDefaults::class)->restrict($data);
334
+ if ($data = array_intersect_key($sanitized, $data)) {
335
  $data = array_filter([
336
  'post_content' => Arr::get($data, 'content'),
337
  'post_date' => Arr::get($data, 'date'),
plugin/Defaults/DefaultsAbstract.php CHANGED
@@ -45,6 +45,7 @@ abstract class DefaultsAbstract implements DefaultsContract
45
 
46
  /**
47
  * The keys that should be mapped to other keys.
 
48
  * Note: Mapped keys should not be included in the defaults!
49
  * @var array
50
  */
45
 
46
  /**
47
  * The keys that should be mapped to other keys.
48
+ * Keys are mapped before the values are sanitized!
49
  * Note: Mapped keys should not be included in the defaults!
50
  * @var array
51
  */
plugin/Defaults/ReviewDefaults.php CHANGED
@@ -38,6 +38,23 @@ class ReviewDefaults extends Defaults
38
  'assigned_posts' => 'array-int',
39
  'assigned_terms' => 'array-int',
40
  'assigned_users' => 'array-int',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  ];
42
 
43
  /**
38
  'assigned_posts' => 'array-int',
39
  'assigned_terms' => 'array-int',
40
  'assigned_users' => 'array-int',
41
+ 'author' => 'text',
42
+ 'avatar' => 'url',
43
+ 'content' => 'text-multiline',
44
+ 'date' => 'date',
45
+ 'date_gmt' => 'date',
46
+ 'email' => 'email',
47
+ 'ip_address' => 'text',
48
+ 'is_approved' => 'bool',
49
+ 'is_modified' => 'bool',
50
+ 'is_pinned' => 'bool',
51
+ 'rating' => 'int',
52
+ 'response' => 'text-multiline',
53
+ 'status' => 'text',
54
+ 'terms' => 'bool',
55
+ 'title' => 'text',
56
+ 'type' => 'text',
57
+ 'url' => 'url',
58
  ];
59
 
60
  /**
plugin/Modules/Html/Field.php CHANGED
@@ -323,7 +323,7 @@ class Field
323
  protected function normalizeFieldName()
324
  {
325
  $name = Str::convertPathToName($this->field['path'], $this->getFieldPrefix());
326
- if ($this->field['is_multi'] && 'checkbox' === $this->field['type']) {
327
  $name = Str::suffix($name, '[]'); // @todo is it necessary to do this both here and in the defaults?
328
  }
329
  $this->field['name'] = $name;
323
  protected function normalizeFieldName()
324
  {
325
  $name = Str::convertPathToName($this->field['path'], $this->getFieldPrefix());
326
+ if (count($this->field['options']) > 1 && 'checkbox' === $this->field['type']) {
327
  $name = Str::suffix($name, '[]'); // @todo is it necessary to do this both here and in the defaults?
328
  }
329
  $this->field['name'] = $name;
plugin/Modules/Sanitizer.php CHANGED
@@ -207,11 +207,11 @@ class Sanitizer
207
  public function sanitizeUserEmail($value)
208
  {
209
  $user = wp_get_current_user();
210
- $value = trim(Cast::toString($value));
211
  if ($user->exists() && !glsr()->retrieveAs('bool', 'import', false)) {
212
  return Helper::ifEmpty($value, $user->user_email);
213
  }
214
- return sanitize_email($value);
215
  }
216
 
217
  /**
@@ -221,11 +221,11 @@ class Sanitizer
221
  public function sanitizeUserName($value)
222
  {
223
  $user = wp_get_current_user();
224
- $value = trim(Cast::toString($value));
225
  if ($user->exists() && !glsr()->retrieveAs('bool', 'import', false)) {
226
  return Helper::ifEmpty($value, $user->display_name);
227
  }
228
- return sanitize_text_field($value);
229
  }
230
 
231
  /**
207
  public function sanitizeUserEmail($value)
208
  {
209
  $user = wp_get_current_user();
210
+ $value = $this->sanitizeEmail($value);
211
  if ($user->exists() && !glsr()->retrieveAs('bool', 'import', false)) {
212
  return Helper::ifEmpty($value, $user->user_email);
213
  }
214
+ return $value;
215
  }
216
 
217
  /**
221
  public function sanitizeUserName($value)
222
  {
223
  $user = wp_get_current_user();
224
+ $value = $this->sanitizeText($value);
225
  if ($user->exists() && !glsr()->retrieveAs('bool', 'import', false)) {
226
  return Helper::ifEmpty($value, $user->display_name);
227
  }
228
+ return $value;
229
  }
230
 
231
  /**
plugin/Review.php CHANGED
@@ -3,6 +3,7 @@
3
  namespace GeminiLabs\SiteReviews;
4
 
5
  use GeminiLabs\SiteReviews\Database\Query;
 
6
  use GeminiLabs\SiteReviews\Defaults\ReviewDefaults;
7
  use GeminiLabs\SiteReviews\Helpers\Arr;
8
  use GeminiLabs\SiteReviews\Helpers\Cast;
@@ -72,7 +73,7 @@ class Review extends Arguments
72
  $values = glsr()->args($values);
73
  $this->id = Cast::toInt($values->review_id);
74
  $args = glsr(ReviewDefaults::class)->restrict($values->toArray());
75
- $args['avatar'] = glsr(Avatar::class)->url($values->avatar);
76
  $args['custom'] = $this->custom();
77
  $args['ID'] = $this->id;
78
  $args['response'] = $this->meta()->_response;
@@ -181,6 +182,7 @@ class Review extends Arguments
181
  }, ARRAY_FILTER_USE_KEY);
182
  $custom = Arr::unprefixKeys($custom, '_custom_');
183
  $custom = Arr::unprefixKeys($custom, '_');
 
184
  return glsr()->args($custom);
185
  }
186
 
3
  namespace GeminiLabs\SiteReviews;
4
 
5
  use GeminiLabs\SiteReviews\Database\Query;
6
+ use GeminiLabs\SiteReviews\Defaults\CustomFieldsDefaults;
7
  use GeminiLabs\SiteReviews\Defaults\ReviewDefaults;
8
  use GeminiLabs\SiteReviews\Helpers\Arr;
9
  use GeminiLabs\SiteReviews\Helpers\Cast;
73
  $values = glsr()->args($values);
74
  $this->id = Cast::toInt($values->review_id);
75
  $args = glsr(ReviewDefaults::class)->restrict($values->toArray());
76
+ $args['avatar'] = glsr(Avatar::class)->url($args['avatar']);
77
  $args['custom'] = $this->custom();
78
  $args['ID'] = $this->id;
79
  $args['response'] = $this->meta()->_response;
182
  }, ARRAY_FILTER_USE_KEY);
183
  $custom = Arr::unprefixKeys($custom, '_custom_');
184
  $custom = Arr::unprefixKeys($custom, '_');
185
+ $custom = glsr(CustomFieldsDefaults::class)->merge($custom);
186
  return glsr()->args($custom);
187
  }
188
 
readme.txt CHANGED
@@ -5,7 +5,7 @@ Tags: reviews, ratings, testimonials, woocommerce, product reviews
5
  Tested up to: 5.8
6
  Requires at least: 5.5
7
  Requires PHP: 5.6
8
- Stable tag: 5.13.0
9
  License: GPLv3
10
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -137,10 +137,16 @@ All documentation can be found in the "Help" page of the plugin. If your questio
137
 
138
  ## Changelog
139
 
 
 
 
 
 
140
  = 5.13.0 (2021-08-01) =
141
 
142
  - Added the $review->author() method on review objects which returns the author name as defined in the settings
143
  - Added the "site-reviews/avatar/attributes" hook which allows you to modify the attributes on the avatar <img> tag
 
144
  - Internal changes to support the upcoming Review Themes add-on
145
  - Renamed the "site-reviews/review/response" hook to "site-reviews/review/responded" (see the related FAQ section)
146
  - Updated the "Common Problems and Solutions"
5
  Tested up to: 5.8
6
  Requires at least: 5.5
7
  Requires PHP: 5.6
8
+ Stable tag: 5.13.1
9
  License: GPLv3
10
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
11
 
137
 
138
  ## Changelog
139
 
140
+ = 5.13.1 (2021-08-02) =
141
+
142
+ - Fixed a possible stored XSS vulnerability which allowed an admin user to add a malicious value when editing a review from the WordPress admin.
143
+ - Fixed the terms toggle which broke due to the multi-checkbox fix in a previous update
144
+
145
  = 5.13.0 (2021-08-01) =
146
 
147
  - Added the $review->author() method on review objects which returns the author name as defined in the settings
148
  - Added the "site-reviews/avatar/attributes" hook which allows you to modify the attributes on the avatar <img> tag
149
+ - Fixed Custom field multi-checkboxes
150
  - Internal changes to support the upcoming Review Themes add-on
151
  - Renamed the "site-reviews/review/response" hook to "site-reviews/review/responded" (see the related FAQ section)
152
  - Updated the "Common Problems and Solutions"
site-reviews.php CHANGED
@@ -7,7 +7,7 @@
7
  * Plugin Name: Site Reviews
8
  * Plugin URI: https://wordpress.org/plugins/site-reviews
9
  * Description: Receive and display reviews on your website
10
- * Version: 5.13.0
11
  * Author: Paul Ryley
12
  * Author URI: https://geminilabs.io
13
  * License: GPL2
7
  * Plugin Name: Site Reviews
8
  * Plugin URI: https://wordpress.org/plugins/site-reviews
9
  * Description: Receive and display reviews on your website
10
+ * Version: 5.13.1
11
  * Author: Paul Ryley
12
  * Author URI: https://geminilabs.io
13
  * License: GPL2