PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 2.10.01
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v2.10.01
2.11.0 2.10.0 2.10.01 2.9.1 2.9.0 2.8.1 2.8.0 2.7.7 2.7.5 2.7.0 2.6.01 2.6.0 2.5.0 2.4.01 trunk 1.0.90 1.0.91 1.0.92 1.0.93 1.0.94 1.0.95 1.0.96 1.0.97 1.0.98 1.0.99 All 78 releases
← All changes | app/Services/CustomSanitizer.php +19 -10 2.7.0 → 2.10.01 View file →
@@ -26,9 +26,9 @@
26 26 $item[$key] = sanitize_text_field($item[$key]);
27 27 }
28 28 }
29 29
30 - $item['permalink'] = sanitize_url($item['permalink']);
30 + $item['permalink'] = sanitize_url(Arr::get($item, 'permalink', ''));
31 31
32 32 if (!empty($item['shape_svg'])) {
33 33 $item['shape_svg'] = self::sanitizeSvg($item['shape_svg']);
34 34 }
@@ -119,8 +119,9 @@
119 119
120 120 private static function sanitizeNode(\DOMNode $node, array $allowed_tags)
121 121 {
122 122 if ($node->nodeType === XML_ELEMENT_NODE) {
123 + /** @var \DOMElement $node */
123 124 if (!isset($allowed_tags[$node->nodeName])) {
124 125 $node->parentNode->removeChild($node);
125 126 return;
126 127 }
@@ -289,9 +290,9 @@
289 290
290 291 $item['emoji'] = self::sanitizeEmoji(Arr::get($item, 'emoji'));
291 292
292 293 if (empty($item['slug'])) {
293 - $item['slug'] = sanitize_title($item['title']);
294 + $item['slug'] = sanitize_title(Arr::get($item, 'title', ''));
294 295 } else {
295 296 $item['slug'] = sanitize_title($item['slug']);
296 297 }
297 298
@@ -300,9 +301,9 @@
300 301 if (isset($item[$key])) {
301 302 $item[$key] = sanitize_text_field($item[$key]);
302 303 }
303 304 }
304 - $item['permalink'] = sanitize_url($item['permalink']);
305 + $item['permalink'] = sanitize_url(Arr::get($item, 'permalink', ''));
305 306
306 307
307 308 if (!empty($item['icon_image'])) {
308 309 $media = Helper::getMediaFromUrl($item['icon_image']);
@@ -320,9 +321,13 @@
320 321
321 322 if (!empty($item['icon_svg'])) {
322 323 $item['icon_svg'] = self::sanitizeSvg($item['icon_svg']);
323 324 }
324 -
325 +
326 + if (!empty($item['shape_svg'])) {
327 + $item['shape_svg'] = self::sanitizeSvg($item['shape_svg']);
328 + }
329 +
325 330 if (Arr::get($item, 'privacy') == 'members_only') {
326 331 $item['membership_ids'] = array_map('sanitize_text_field', (array)Arr::get($item, 'membership_ids', []));
327 332 }
328 333
@@ -353,18 +358,22 @@
353 358 return $html;
354 359 }
355 360
356 361 $tags = wp_kses_allowed_html('post');
357 - $tags['style'] = [
358 - 'types' => [],
359 - ];
360 362
361 - // iframe
363 + // No <style> element: kses filters style="" attributes but never the text content
364 + // of a <style> block, so allowing it would let any role that can author this markup
365 + // persist CSS (@import, attribute-selector data exfiltration, UI redress) against
366 + // every viewer. Embed/media HTML never needs a <style> element.
367 +
368 + // iframe. Note there is deliberately no 'srcdoc' here: a srcdoc iframe without a
369 + // sandbox attribute is same-origin with the portal, so allowing it would let any
370 + // role that can author embed markup run script against every viewer. Real embed
371 + // providers only ever use src.
362 372 $tags['iframe'] = [
363 373 'width' => [],
364 374 'height' => [],
365 375 'src' => [],
366 - 'srcdoc' => [],
367 376 'title' => [],
368 377 'frameborder' => [],
369 378 'allow' => [],
370 379 'class' => [],
@@ -370,9 +379,8 @@
370 379 'class' => [],
371 380 'id' => [],
372 381 'allowfullscreen' => [],
373 382 'referrerpolicy' => [],
374 - 'style' => [],
375 383 ];
376 384
377 385 $tags = apply_filters('fluent_community/allowed_html_tags', $tags);
378 386
@@ -474,8 +482,9 @@
474 482 public static function santizeSpaceSettings($settings = [], $privacy = 'public')
475 483 {
476 484 $yesNotFields = [
477 485 'restricted_post_only',
486 + 'verified_post_only',
478 487 'can_request_join',
479 488 'show_paywalls',
480 489 'show_sidebar',
481 490 'hide_members_count',