Should we sanitize and validate the apply_filters() like the examples below?

  1. absint( apply_filters( 'slug_excerpt_length', 35 ) );

  2. wp_kses_post( apply_filters( 'slug_excerpt_more', '…' ) );

  3. esc_url( apply_filters( 'slug_login_url', home_url( '/' ) ) );

I am asking this question, cause I have never seen this before. Actually we add some validation to prevent breaking something when the user adds something wrong in the child-theme.

I wonder what you think about it.

1 Answer 1


There's some confusion here, because not all of these are validation, there are 2 others that are necessary to understand what's appropriate:

  • validation
  • sanitisation
  • escaping


Sanitisation makes things clean and well formed

This cleans up the data, e.g. trimming trailing spaces, removing letters in a number field, making an all lowercase field all lowercase, etc

E.g. The user entered " Banana ", so turn it into "Banana"

Sanitisation is the first thing that should happen to input that comes from somewhere else, e.g. when processing a form, sanitise the data before doing anything with it. The same of any data that comes from a remote connection etc

Popular sanitising methods include:

  • stripping out HTML or particular tags via wp_kses wp_strip_all_tags etc
  • Removing ranges of characters, such as non-numeric characters, or punctuation
  • Trimming trailing characters such as spaces etc
  • Applying bounds such as restricting values to within a range ( this could instead be implemented as a validation check )


Validation checks if things are valid

Validation checks that the phone number the user entered is actually a phone number. It's a true or false check.

E.g. Is the fruit the user chose actually a fruit?

This should be done on input after sanitising, and if validation fails, abort, popular methods of validation include:

  • functions like is_numeric etc
  • regular expressions, useful for things like phone numbers or URLs, things that have an expected format
  • checking roles and capabilities to verify the user actually has the ability to do the intended action
  • nonce checks
  • whitelists of predefined allowed values
  • checking values sit within valid ranges, e.g. nobody has a 200 character long telephone number, nor would somebody live in house number -2000000


Escaping makes values safe for output, and enforces assumptions

Escape late, escape often.

Escaping isn't talked about much, but imagine it using the fruit example from above. Escaping is like a conveyor belt with a fruit shaped cut out. You always get something fruit shaped at the end. If a fruit passes through, it's untouched, but if a malicious actor goes through, a mangled but safe fruit shaped version pops out the end.

Escaping is therefore all about enforcing assumptions. E.g. in an <a> tag, the href attribute should contain a URL. But this might not be the case, escaping allows us to swap the "should contain" to a "will always contain", providing us a guarantee. This prevents somebody starting their URL with "/> and inserting arbitary HTML.

Escaping should always be done on output, at the very latest point possible to ensure nothing was modified. Escaping is also context sensitive. You would use esc_attr to escape HTML attributes, but if it's a href or src attribute, we would use esc_url to indicate it's a URL we're intending to output.

A Note on Double Escaping and wp_kses

You can sanitize and validate multiple times, but you should only escape a value once. This is because double escaping can double encode values, and in some circumstances can allow content to break out of escaping.

wp_kses_post and wp_kses are also unusual in that they can be used to escape, and to sanitise, and can be used multiple times on a value.

A Note on Early Escaping

This is a near mortal sin that can almost undo everything escaping gives you. Once something has been escaped, we know it is safe and secure to output it, but, if we then assign it to a variable, who knows what might happen to it between escaping and output. If that variable gets modified, passed to a function, or piped through a filter, it's no longer safe, it's status is a mystery. We can escape it again but now we've double escaped, so we might have made safe data dangerous, or mangled good data.

So About Those Filters

Should we sanitize and validate the apply_filters() like the examples below?

It depends on the context

On input:

  • Sanitise
  • then validate
  • if it's valid then proceed, else reject

On output to the browser/requests/etc:

  • you can sanitise and validate once fetched from the database if you like, but the #1 priority is to escape, escape only once, and do it on the moment of output. Don't store it in a variable, that's early escaping and it's dangerous
  • Escape after filtering, not before, who knows what the filter did to a known safe value, once the value is returned from the filter its safety and status are a mystery
  1. absint( apply_filters( 'slug_excerpt_length', 35 ) );

Great we now know this value is definitely a number, and a positive number too. If we prefix this statement with echo then that's a safe escaped value. Else it's just sanitisation that's cleaned up the value.

  1. wp_kses_post( apply_filters( 'slug_excerpt_more', '&hellip;' ) );

Great, this is both sanitising and escaping if we immediately output it, but if we save it to a variable, it's just sanitising.

  1. esc_url( apply_filters( 'slug_login_url', home_url( '/' ) ) );

This is escaping, and needs an echo statement. If we assign this to a variable then the escaping was for nought and we introduce a precarious situation.

If the question on the other hand is, should we double check the return values of filters? Yes, that would be wise, but overcautious. In that scenario I would expect that this would be testing for filters that aren't implemented properly, e.g. returning text where a number is expected. In that scenario, validation is the only option, escaping and sanitisation would be inappropriate.


  • When using the_content filter, pass the value through wp_kses_post then pass it into the filter and immediatley echo, e.g. echo apply_filters( 'the_content', wp_kses_post( $dangerous ) );
  • In shortcodes, escape and use output buffers if you must, so that you can return a string
  • This is a really good explanation. I didn't expect so much information. Thank you guys. <3
    – Asaf
    Commented Jul 23, 2018 at 8:49
  • Epic answer, thanks. Is it safe to do this in a function? Eg: return esc_url( apply_filters( 'slug_login_url', home_url( '/' ) ) ); at the end of the function and then echo myfunction() in the template? Or should the escape be outside the function, like echo esc_url( myfunction() ) to be fully secure?
    – Shoelaced
    Commented Sep 1, 2021 at 13:33
  • 1
    no that would be early escaping, it would be safer to do echo esc_url( myfunction() ). Otherwise we have to trust that myfunction is used correctly, and who needs trust that it should be used correctly when we can guarantee it? functions that return things should either output escaped content, or be escaped themselves. If myfunction returned escaped HTML, we now have 2 problems: 1) we don't know how many times its been escaped and 2) who's supposed to do the escaping? How do we know if myfunction did it or if we should do it?
    – Tom J Nowell
    Commented Sep 1, 2021 at 14:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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