What is the difference between esc_html filter vs attribute_escape filter?

It would appear that out of the box, there isn’t a difference

function esc_html( $text ) {
    $safe_text = wp_check_invalid_utf8( $text );
    $safe_text = _wp_specialchars( $safe_text, ENT_QUOTES );
    /**
     * Filters a string cleaned and escaped for output in HTML.
     *
     * Text passed to esc_html() is stripped of invalid or special characters
     * before output.
     *
     * @since 2.8.0
     *
     * @param string $safe_text The text after it has been escaped.
     * @param string $text      The text prior to being escaped.
     */
    return apply_filters( 'esc_html', $safe_text, $text );
}
function esc_attr( $text ) {
    $safe_text = wp_check_invalid_utf8( $text );
    $safe_text = _wp_specialchars( $safe_text, ENT_QUOTES );
    /**
     * Filters a string cleaned and escaped for output in an HTML attribute.
     *
     * Text passed to esc_attr() is stripped of invalid or special characters
     * before output.
     *
     * @since 2.0.6
     *
     * @param string $safe_text The text after it has been escaped.
     * @param string $text      The text prior to being escaped.
     */
    return apply_filters( 'attribute_escape', $safe_text, $text );
}

The only difference between the 2 functions is the filter applied at the end. WordPress doesn’t add anything to these filters, so in a standard WP install they are non-operations. They’re provided in the edge case that somebody might need them.

Quick Q&A

So by default they’re identical?

Yes! The esc_attr and esc_html functions have the same implementation

Are the filters identical?

The only difference is they have different names, they work the same way, they’re used the same way, and neither filter is used in core.

Do the filters do anything?

No! All the escaping is done in the function when wp_check_invalid_utf8 and _wp_specialchars are called.

The filters don’t do the escaping, they’re an opportunity for plugins to do additional checks and processing.

Are there any edge cases?

Only if you use the filters, say you hooked into esc_html but not attribute_escape, or vice versa. For a standard WP install, the 2 functions are identical, with no difference.

Why attribute_escape and not esc_attr?

Backwards compatibility. There used to be an attribute_escape function, which is now marked as deprecated after the esc_ style functions were added.

Why would I use these filters?

¯\_(ツ)_/¯ this would be a rare situation. Some people might abuse it in the same way translation APIs are abused to search replace text. This is already bad practice as those filters get called a lot a small speed loss is magnified thousands of times

But consider that if you’re not careful you may compromise the security of these functions by undoing the escaping they added, or adding unescaped content at the end. For that reason the filters are dangerous.

Do I Need To Worry About This?

No. You only need to worry if you’ve made use of those filters, which by itself should have set off massive red alarms that something in your development went seriously wrong.

The functions esc_attr and esc_html are safe to use, and escape content. You have an ethical and moral obligation to use them if you value the security of your code

Does this mean I should just use esc_html?

No, escaping is all about setting expectations. If you’re expecting an attribute, use esc_attr. Just because it’s functionally the same at the moment, doesn’t mean that won’t change in the future with a security release

Leave a Comment