PluginProbe
Elementor Website Builder – more than just a page builder / 4.3.0-beta3
Elementor Website Builder – more than just a page builder v4.3.0-beta3
4.3.0-beta3 4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 4.1.0-dev1 All 452 releases
← All changes | includes/utils.php +90 -1 4.1.54.3.0-beta3 View file →
@@ -46,8 +46,29 @@
46 46 'section',
47 47 'span',
48 48 ];
49 49
50 + /**
51 + * Tags that must never be usable as an HTML wrapper tag, regardless of what
52 + * `elementor/allowed_html_wrapper_tags` filters return. These are the classic
53 + * script-execution / markup-injection vectors (XSS), so they're enforced as a
54 + * hard denylist rather than left to filter authors to avoid re-adding them.
55 + */
56 + const FORBIDDEN_HTML_WRAPPER_TAGS = [
57 + 'script',
58 + 'iframe',
59 + 'object',
60 + 'embed',
61 + 'style',
62 + 'link',
63 + 'meta',
64 + 'base',
65 + 'noscript',
66 + 'template',
67 + 'svg',
68 + 'math',
69 + ];
70 +
50 71 const EXTENDED_ALLOWED_HTML_TAGS = [
51 72 'iframe' => [
52 73 'iframe' => [
53 74 'allow' => true,
@@ -775,8 +796,45 @@
775 796 }
776 797 }
777 798
778 799 /**
800 + * @var string[]|null
801 + */
802 + private static $resolved_allowed_html_wrapper_tags;
803 +
804 + /**
805 + * Get allowed HTML wrapper tags.
806 + *
807 + * @since 4.4.0
808 + *
809 + * @return string[]
810 + */
811 + public static function get_allowed_html_wrapper_tags(): array {
812 + if ( null !== self::$resolved_allowed_html_wrapper_tags ) {
813 + return self::$resolved_allowed_html_wrapper_tags;
814 + }
815 +
816 + /**
817 + * Allowed HTML wrapper tags.
818 + *
819 + * Filters the list of allowed HTML tag names used by `validate_html_tag()`.
820 + *
821 + * Note: tags in `Utils::FORBIDDEN_HTML_WRAPPER_TAGS` (e.g. `script`, `iframe`,
822 + * `object`) are always stripped after this filter runs and cannot be re-added,
823 + * to prevent XSS via a wrapper tag that executes script or embeds external content.
824 + *
825 + * @since 4.4.0
826 + *
827 + * @param string[] $tags A list of lowercase HTML tag name strings.
828 + */
829 + $tags = apply_filters( 'elementor/allowed_html_wrapper_tags', self::ALLOWED_HTML_WRAPPER_TAGS );
830 +
831 + self::$resolved_allowed_html_wrapper_tags = self::normalize_allowed_html_wrapper_tags( $tags );
832 +
833 + return self::$resolved_allowed_html_wrapper_tags;
834 + }
835 +
836 + /**
779 837 * Validate an HTML tag against a safe allowed list.
780 838 *
781 839 * @param string $tag
782 840 *
@@ -782,12 +840,37 @@
782 840 *
783 841 * @return string
784 842 */
785 843 public static function validate_html_tag( $tag ) {
786 - return $tag && in_array( strtolower( $tag ), self::ALLOWED_HTML_WRAPPER_TAGS ) ? $tag : 'div';
844 + return $tag && in_array( strtolower( $tag ), self::get_allowed_html_wrapper_tags(), true ) ? $tag : 'div';
787 845 }
788 846
789 847 /**
848 + * @param array $tags
849 + *
850 + * @return string[]
851 + */
852 + private static function normalize_allowed_html_wrapper_tags( array $tags ): array {
853 + $normalized_tags = [];
854 +
855 + foreach ( $tags as $tag ) {
856 + if ( ! is_string( $tag ) ) {
857 + continue;
858 + }
859 +
860 + $tag = strtolower( $tag );
861 +
862 + if ( in_array( $tag, self::FORBIDDEN_HTML_WRAPPER_TAGS, true ) ) {
863 + continue;
864 + }
865 +
866 + $normalized_tags[] = $tag;
867 + }
868 +
869 + return array_values( array_unique( $normalized_tags ) );
870 + }
871 +
872 + /**
790 873 * Safe print a validated HTML tag.
791 874 *
792 875 * @param string $tag
793 876 */
@@ -837,8 +920,14 @@
837 920 }
838 921 }
839 922
840 923 echo wp_kses( $text, $allowed_html );
924 + }
925 +
926 + public static function kses_post_deep( $data ) {
927 + return map_deep( $data, function ( $value ) {
928 + return is_string( $value ) ? wp_kses_post( $value ) : $value;
929 + } );
841 930 }
842 931
843 932 public static function is_elementor_path( $path ) {
844 933 $path = wp_normalize_path( $path );