Close this search box.
Close this search box.

WordPress Data Sanitization and Validation

Escaping HTML

When printing variables to the page we need to be mindful of how the browser will interpret them. Let’s consider the following example:

<h1> <?php echo $title; ?> </h1>

Suppose $title = <script>alert(‘Injected javascript’)</script>. Rather than displaying the HTML <script> tags, they will be interpreted as HTML and the enclosed javascript would be injected into the page.

This form of injection (as also demonstrated in the search form example) is called Cross-site scripting and this benign example belies its severity. Injected script can essentially control the browser and ‘act on behalf’ of the user or steal the user’s cookies. This becomes an even more serious issue if the user is logged in. To prevent variables printed inside HTML being interpreted as HTML, WordPress provides the well known esc_html function. In this example:

<h1> <?php echo esc_html($title); ?> </h1>

Escaping Attributes

<?php $value = 'my-value" onfocus="alert(\"Injected javascript\")"'; ?>
<input type="text" name="myInput" value="<?php echo $value;?>"/>

To escape unsafe characters (such as quotes, and double-quotes in this case), WordPress provides the function esc_attr. Like esc_html it replaces ‘unsafe’ characters by their entity equivalents. In fact, at the time of writing, these functions are identical – but you should still use the one that is appropriate for the context.

For this example we should have:

<?php $value = 'my-value" onfocus="alert(\"Injected javascript\")"'; ?>
<input type="text" name="myInput" value="<?php echo esc_attr($value);?>"/>

Escaping URLs

Let’s now look at another common practise, printing variables into the href attribute:

<a href="<?php echo $url;?>" title="Link Title"> Link Text </a>

Clearly it is vulnerable to the same form of attack as illustrated in escaping HTML and attributes. But what if the $url was set as follows:

$url = 'javascript:alert(\'Injected javascript\')'

On clicking the link, the alert function would be fired. This contains no HTML, or any quotes that allow it to jump out of the href attribute – so esc_attr is not sufficient here. This is why context matters: esc_attr($url) would be safe in the title attribute, but not for the href attribute – and this is because of the javascript protocol – which while perfectly valid – is not to be considered safe in this context. Instead you should use:

  • esc_url – for escaping URLs that will be printed to the page.
  • esc_url_raw – for escaping URLs to save to the database or use in URL redirecting.

esc_url strips out various offending characters, and replaces quotes and ampersands with their entity equivalents. It then checks that the protocol being used is allowed (javascript, by default, isn’t).

What esc_url_raw does is almost identical to esc_url, but it does not replace ampersands and single quotes (which you don’t want to, when using the URL as an URL, rather than displaying it).

In this example, we are displaying the URL, so we use esc_url:

<a href="<?php echo esc_url($url);?>" title="Link Title"> Link Text </a>

Learning Resources