5

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?

2 Answers 2

7

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

5
  • Nice replies Tom. I wonder since I read that for a custom template in WP you should go through a template file checklist and in it there were one saying that you should use <meta charset="<?php bloginfo( 'charset' ); ?>" /> in the head. Should I / can I esc_attr this one too? And then try to never use it again.
    – emcolsson
    Commented Mar 17, 2017 at 15:35
  • This is just wrong, as stated in my answer widget titles for example should not be escaped late, but sanitized early, otherwise plugins which add styling to it will fail. Core is seriously non consistent (surprise surprise) with where the output of the APIs is escaped and where it is not. Commented Mar 17, 2017 at 16:40
  • ... and obviously escaping depends on context so the esc_attr(get_bloginfo() here might be misleading Commented Mar 17, 2017 at 16:48
  • another exception just poped in my head is oembed result APIs which should be served as raw HTML and not be escaped at all Commented Mar 17, 2017 at 16:50
  • I would strongly err on the side of security over edge cases, for situation that require markup, pass it through wp_kses_post or wp_kses. Sanitise early, escape late
    – Tom J Nowell
    Commented Mar 18, 2017 at 16:30
1

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.

2
  • Its escalating quickly! No, jokes aside, thanks for the answer and I will have to read up on this even more to make it right. One question though - are there negative aspects of adding escapes to stuff that maybe dont need it? If Ill start to escaping as much as I think is needed, may I do harm if they didnt need it fro mthe beginning? Im thinking of echos mostly, for user inputs as in contact forms and other labels.
    – emcolsson
    Commented Mar 17, 2017 at 10:11
  • yes, you should not escape the escaped as something that rendered as ">" (escaped as &gt;) will render as &gt; (escaped as &amp;gt;) Commented Mar 17, 2017 at 11:18

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.