esc_attr / esc_html / esc_url in echos

Hi I am trying to understand when and why I should use these esc-alternatives and so far I think I understand that it is needed to secure that input is not containing wrong characters and in that causing errors/security threats.

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?

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?

Solutions Collecting From Web of "esc_attr / esc_html / esc_url in echos"

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="<?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

If the values that are in need of escaping are generate fully from your code, as it is usually in admin screens, then yes, always escape.

Things get more complex when you need to output a result of a core API as they are not consistent and it is better to dig into the code to see if the values returned by the API are already escaped, the_title is probably escaped, but if you use API to get a a tag name, you will need to escape it.

An even harder situation is when your output is just an input to some higher layer of core, like a value you return in a filter, or widgets. Widgets are nasty as on the front end side you should escape all the values you got in the form except for the widget title.

Rule of thumb, if there is a comparable functionality in core or a core theme, take a look how they handle escaping and do the same.