8

What is the exact difference between esc_html and attribute_escape filter?

esc_html() uses esc_html filter and esc_attr() uses attribute_escape filter. Both encodes < > & " ' (less than, greater than, ampersand, double quote, single quote).

I'm interested to know what exactly makes them different in terms of security (escaping).

  • well, if they were not different there would not be a need in having the two of them.... the question IMO is just not clear, it is like asking what is the difference between the_content and the_excerpt filters – Mark Kaplun Apr 24 '17 at 12:50
  • 1
    I think that's what he's asking, how are they different and why? – Tom J Nowell Apr 24 '17 at 12:54
  • @TomJNowell, well one is called to escape attributes and the other to escape general HTML. That explains the why, and mostly explains the how as well ;) Where should an answer start here, with explaining the difference between the characters allowed in attributes and general html? this sounds a little too basic (but might be what the OP asks about I guess) – Mark Kaplun Apr 24 '17 at 13:12
  • 2
    That would be good, but an example of something esc_attr escapes that esc_html doesn't would be useful, afterall why not use esc_html everywhere? If it's obvious to you it might not seem like a good question but it isn't obvious to the asker how these 2 functions differ given they both escape the characters expected – Tom J Nowell Apr 24 '17 at 13:30
8

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

| improve this answer | |
  • Thanks for the answer. Maybe I need to rephrase my question. I'm more interested to know if there is any difference in the core implementation of the two filters mentioned above. This would really help us (developers) to know how escaping works in attributes and HTML. – djadmin Apr 24 '17 at 16:25
  • Those filters aren't used by Core, they're provided for plugins should the need arise. I strongly advise against using them however for security reasons – Tom J Nowell Apr 24 '17 at 17:45
  • "The esc_html and attribute_escape filters are thus very dangerous." I really don't understand this point. If we do not use this, then how are we supposed to escape user inputs to prevent from XSS? – djadmin Apr 25 '17 at 7:14
  • As you said, they pass through a filter before exiting. My original question is how are these two filters different in terms of implementation. I believe there would be some edge case which esc_html filter escape and attribute_escape filter don't or vice versa. – djadmin Apr 25 '17 at 7:17
  • They don't. The filters are provided for 3rd party code and aren't used by Core. Core does not hook into the filters, nor does it do anything with them. Those edge cases would need to be written by a theme or plugin developer, at which point it'd be obvious as you'd be the person who wrote it – Tom J Nowell Apr 25 '17 at 12:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.