I’m the original author of that article, hopefully I can elaborate on my point (“Rule 4”).
The ‘data’ in this case is the value entered by the user:
$raw = '<textarea name="my-textarea"></textarea> Hello World';
There are two contexts in which we display this data in some form:
- The front-end view, where we wish to render the HTML entered by the user
- The widget admin view, where we wish to allow the user to view and edit the HTML they have entered.
For (1), we might doing something like the following:
class My_Widget extends WP_Widget {
...
public function widget( $args, $instance ) {
// outputs the content of the widget
...
echo $raw;
...
}
...
}
This is ‘fine’. Normally we might not want the widget editor to be able insert iframes, script tags or unbalanced HTML – but here, for illustrative purposes, we’re being entirely permissive. The point is when we’re printing a variable’s content to be rendered as HTML in a HTML page we don’t need to escape anything.
But, we have to treat the same variable differently when we wish to display it in a different format (i.e. we wish to print the mark-up inside a teaxtarea rather than actually render it as HTML).
class My_Widget extends WP_Widget {
...
public function form( $instance ) {
// This is wrong!
...
echo '<textarea>' . $raw . '</textarea>';
...
}
...
}
In the above we want to display the mark-up not render it, but we not doing anything to prevent $raw
being interpreted as HTML. This is dangerous; HTML is not safe as a value for the textarea. While for most HTML, it will display as intended, if it contains </textarea>
the form will ‘break’, and inject HTML into the widget admin page, as demonstrated in the article.
Escaping in this context, means preventing $raw
being interpreted as HTML. There’s a useful function WordPress provides for this instance:
class My_Widget extends WP_Widget {
...
public function form( $instance ) {
// This is wrong!
...
echo '<textarea>' . esc_textarea( $raw ) . '</textarea>';
...
}
...
}