Sanitizing HTML Input and Escaping HTML Output

If you’re using our layout builder or trying to save any other form in your theme, and you’re running into the issue of not being able to save and/or output more complex HTML, you may have stumbled across this article.

There are two sides to discussing this topic. There’s the (1) issue of saving the HTML to your database, and then (2) outputting it on the frontend of your website.

Saving Unfiltered HTML to the Database

In order to save totally unfiltered HTML from our Layout Builder and other framework admin areas — like Theme Options, Meta Boxes, etc. — to your database, you’ll need to be logged in with an account that has the unfiltered_html capability.

In other words, make sure you’re logged in as an Administrator.

If you’re wanting to reassign WordPress’s unfiltered_html capability to lower user levels, there are plugins like this or this, that can help with that.

Displaying Unfiltered HTML on Your Website

Now, there’s a bit of a hiccup with all this. Our framework takes some extra steps in security for everything it outputs, by escaping and validating the HTML of content blocks. So, even though you’ve saved unfiltered HTML to your database while logged in as an Administrator, it still may not output how you’re expecting on the frontend.

There are two ways you can go about fixing this. Before deciding, it may be good to read up about data validation in WordPress and understand the security vulnerabilities and all this. Here are some helpful articles I’ve found:

The Quick, Less Safe Way

The quick and dirty way to avoid this issue is to simply disable all filtering on output. In our framework, most of our custom content blocks are passed through the same filtered function. Within there we’ve added a filter that can be utilized called themeblvd_disable_kses.

Simply filter it to false to remove our data validation and filtering on the output, on the frontend only.

add_filter('themeblvd_disable_kses', '__return_true');

The problem with this is that if somehow your MySQL database has been compromised, now there’s nothing to protect these malicious scripts from being printed on your website.

The Long, More Safe Way

In order to really keep things secure, I’d suggest taking the time to manually extend the allowed HTML tags in these content blocks’ output.

The framework filters the output of these content blocks by using wp_kses(). And for the allowed HTML tags passed in, we use the standard WordPress global $allowedposttags and add onto it a bit.

You can filter in your own allowed HTML tags by utilizing our themeblvd_allowed_tags filter.

What are you filtering? And how do you know what tags are currently allowed? — In your child theme’s functions.php, use the following code temporarily to print out the array you’ll be adding to.

function print_allowed_tags() {
	$tags = themeblvd_allowed_tags();
	echo '<pre>'; print_r($tags); echo '</pre>';
add_action('themeblvd_before', 'print_allowed_tags');

… Please don’t do this on a live site! 🙂

Now, you’ll see a big, giant array of all the HTML tags you can output formatted something like this:

    [a] => Array
            [href] => 1
            [rel] => 1
            [rev] => 1
            [name] => 1
            [target] => 1
            [class] => 1
            [id] => 1
            [style] => 1
            [title] => 1
            [role] => 1

    And so on...

Each top-level array key represents an HTML tag. For example, the HTML tag the portion above is referring to is <a>. Then, all of the keys within are referring to the accepted parameters within that tag.

So, let’s say I have an HTML tag <foo> I want to output, along with a parameter for it, bar. Something like this:

<foo bar="whatever">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.</p>

To allow this, I could filter onto themeblvd_allowed_tags like this:

function my_allowed_tags( $tags ) {

    $tags['foo'] = array();
    $tags['foo']['bar'] = true;

    // Continue adding more tags and parameters ...

    return $tags;
add_filter('themeblvd_allowed_tags', 'my_allowed_tags');