Do Not Understand → Rule No. 4: Making Data Safe Is About Context [closed]

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:

  1. The front-end view, where we wish to render the HTML entered by the user
  2. 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>';
    ...
   }
   ...
}