It came up at the Minneapolis WordPress User Group that I spoke at last night and on the Genesis Slack chat this morning. It appears to be the question of the day…
So should I escape it?
Yes! You should (late) escape (or sanitize) all output, all the time.
But…
Always and forever — ignore this advice at your peril.
Why?
Because security.
Even if you sanitized the data (as WordPress does) when you save it…
- How do you know what you saved is what you’re retrieving (e.g. it wasn’t altered after the fact)?
- That what you retrieved is what you have now (filters can alter the output at many stages along the way)?
- Are you 100% absolutely sure? Escape (or sanitize) it anyways — it almost never hurts and only helps.
Thus, you should escape or sanitize output as late as possible (just before it’s sent to the browser).
Ok, so how do I do that?
Anytime you’re going to echo output to the browser that comes from the user, the database, an API call, etc. you need to sanitize and/or escape the output before sending it down the series of tubes to the browser.
To the codex!
Validating Sanitizing and Escaping User Data
The one’s you’ll use most often are:
- esc_html() — general HTML output.
- esc_attr() — when you’re echoing into an HTML attribute (like “class”, “title”, etc).
- esc_url() — urls (links, images, etc).
What does escaping output actually do?
Instead of outputting <script>…</script> it outputs <script>…</script> which is unsightly, but as the browser doesn’t execute the code the the attack is avoided.
You can see how HTML encoding/decoding works using an online tool.
What if I don’t want to see that strange code on my site?
You could use strip_tags(), but wp_filter_nohtml_kses() is more comprehensive. That will remove all HTML before output. You don’t have to escape at that point — but it never hurts as escaping will catch special characters that should be encoded in HTML for compatibility.
What if I need a <i> or <b> tag in my title?
No problem, you just need to sanitize instead of escape.
wp_kses_post() is the easiest route to take as it uses the global “whitelist” of allowable tags baked into WordPress. That does allow inline <script> and <iframe> tags for Administrator users — so it’s not a silver bullet.
If you want to be safe, specify your own whitelist using wp_kses().
$allowed = array(
'strong' => array(),
'em' => array(),
'b' => array(),
'i' => array(),
);
echo wp_kses( get_the_title(), $allowed
);
I would like another opinion!
OK, here’s WordPress VIP’s take on the matter:
The Importance of Escaping All The Things