Site icon Karen Attfield

The unfiltered_html permission: unexpected HTML stripping on multisites

Photo by cottonbro studio: https://www.pexels.com/photo/close-up-shot-of-a-man-5474036/

If you’re working with blocks, it’s worth keeping in mind the effect of the unfiltered_html permission and how it can cause issues on multisites.

The unfiltered_html permission, if not granted, will result in HTML filtering via the wp_kses function.

On single-site WordPress installations, administrators have this capability. However on multisite installations, administrators do not have this capability – only super admins do. Here is where this check is happening in the WordPress core code.

How does this affect block development?

One way this could be an issue for block development is if you create a block that embeds third party content, it’s possible that some content may not properly embed unless this capability is added.

However what prompted me to create this article though was a situation where a block can be added on a multisite by an admin (not super admin), and that user ends up seeing a block validation error. This will be due to some of the HTML being included in your block save function. In my case it was tabindex. This is not one of the allowed tags for use by kses by default in WordPress.

How to prevent block validation issues in block development

If you’ve noticed attributes being stripped when testing on multisites, one workaround would be to consider adding them when rendering the block (via PHP) – so they’re only added on the front-end. This can prevent block validation issues if you had been adding HTML attributes via your save.js file. They’ll likely still be stripped, but at least your users won’t be met with block validation issues.

How to prevent block validation issues on a site level

Removing the unfiltered_html permission

On a site-by-site level, you can remove this permission in a few ways. Bear in mind with some examples that you can enable this for all user roles or capabilities, which you may not want to do depending on what kind of user roles exist on your site… allowing this for any user could be a security risk if they post malicious / poorly formatted code.

In wp-config.php, for all users:

define('DISALLOW_UNFILTERED_HTML', false);

You can hook into the map_meta_cap to provide capabilities to all or specific users. Here’s a code snippet (that you can add using a code snippets plugin for example) that adds the capability to anyone who has the ability to edit posts:

function add_unfiltered_html_capability( $caps, $cap, $user_id ) {
    if ( 'unfiltered_html' === $cap && user_can( $user_id, 'edit_posts' ) )  {
        $caps = array( 'unfiltered_html' );
    }
	return $caps;
}
add_filter( 'map_meta_cap', 'add_unfiltered_html_capability', 1, 3 );

Here is another that adds the capability to the editor role:


function add_unfiltered_html_capability() {
    $role = get_role('editor');
    $role->add_cap('unfiltered_html');
}
add_action('init', 'add_unfiltered_html_capability');

To add the capability to all users on a site, just return array( 'unfiltered_html' );.

Using a plugin

Some user role plugins will allow you the ability to add this capability for specific users.

Allowing the specific attribute

Also on a site level, you can add the attribute that is otherwise being stripped via the wp_kses_allowed_html filter. here is an example to add back the tabindex attribute for the img tag:


add_filter( 'wp_kses_allowed_html', function( $allowed_tags, $context ) {
	if ( 'post' !== $context ) {
		return $allowed_tags;
	}

	if ( isset( $allowed_tags['img'] ) ) {
		$allowed_tags['img']['tabindex'] = true;
	}

	return $allowed_tags;
}, 10, 2 );

Summary

There are far more ways to prevent validation issues on a site level than on a block development level, but ultimately when developing that is where you generally want to prevent these issues. That said, depending on the attribute you want to have included there could be good reason for that to not be allowed by default, and you may want to suggest users of the block allow the capability or allow the attribute themselves if they prefer.

Exit mobile version