| @@ -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', |