Yes! You should always be escaping
Escape Late, Escape Often
Escaping is about intent, if you intend to output a URL, use esc_url
, and it will definately be a URL ( if the data is malicious it will be made safe )
What I still wonder is should I always use esc_attr in HTML fields, or example the input fields of a contact form? And should I always use esc_url for all my own urls, for example image src paths?
If it’s a hardcoded URL? E.g. "http://example.com"
? No, we know it’s safe
If it’s a URL from a function or some other source? E.g. echo get_permalink()
or echo $url
?
Yes, you should escape there’s no way to know if it’s safe
If it’s a function that outputs internally and doesn’t require an echo
statement? E.g. the_permalink()
? No there’s no way to escape this, the function needs to escape internally. Output buffers can be used in emergencies, but that path leads to madness
And what about the_title()? Should I use one of these escapes to all echos in my code or only where there are possible input from users?
There’s no way to escape a function that outputs internally. the_title
should be good to use, as are the others
With 1 Exception
bloginfo
Avoid this function at all costs, for security reasons. bloginfo
doesn’t always escape internally, and as it outputs internally there’s no way to add escaping.
The solution
Use get_bloginfo
and escape the result, e.g.
<a href="https://wordpress.stackexchange.com/questions/260427/<?php echo esc_url( get_bloginfo("site' ) ); ?>">
get_bloginfo
returns rather than outputs the value, allowing us to use escaping functions.
A Brief Note on Filters
Sometimes you want to pass things through a filter, such as the_content
, but escaping the result will strip out tags.
For example, this will strip any embedded videos present:
echo wp_kses_post( apply_filters( 'the_content', $stuff ) );
The solution is instead to do this:
echo apply_filters( 'the_content', wp_kses_post( $stuff ) );
The idea being that we know the input is safe, therefore the output must be safe. This assumes that any code running on that filter also escapes accordingly. Do this for these situations with WP Core filters, but avoid needing this in your own filters and code as much as possible