I need some help here.

While developing a theme, I want to make sure there are no security issues. So all dynamic data must be correctly escaped for the context where it is rendered.

I know how to escape the following:

  • If ‘echo’ in the attribute, use esc_attr
  • If ‘echo’ in class attribute, use sanitize_html_class
  • If ‘echo’ in plain text, use esc_html
  • If ‘echo’ in translation, use esc_html__, esc_html_e, esc_attr_e, etc

But there’re two areas in which I am not sure what to do.

  1. What escaping should I use if user output may contain some html tags, like ’em’ or ‘strong’?

Example:

<?php $subtitle = get_post_meta($post_id,'subtitle', true); ?>
<h3 class="subtitle"><?php echo $subtitle; ?></h3>

Note that “wp_kses is an expensive function, so it should only be run when data is saved, not displayed”
Proof here

  1. What escaping should I use to output CSS styles?

Example:

<style type="text/css"><?php echo $css; ?></style>

1
1

Let’s go and see what would core do.

In default-filters.php here is what content output passes through:

add_filter( 'the_content', 'wptexturize'        );
add_filter( 'the_content', 'convert_smilies'    );
add_filter( 'the_content', 'convert_chars'      );
add_filter( 'the_content', 'wpautop'            );
add_filter( 'the_content', 'shortcode_unautop'  );
add_filter( 'the_content', 'prepend_attachment' );

None of these are dedicated security/escaping functions really.

It is similar for comments, which come from random visitors altogether and not even semi-trusted site authors:

add_filter( 'comment_text', 'wptexturize'            );
add_filter( 'comment_text', 'convert_chars'          );
add_filter( 'comment_text', 'make_clickable',      9 );
add_filter( 'comment_text', 'force_balance_tags', 25 );
add_filter( 'comment_text', 'convert_smilies',    20 );
add_filter( 'comment_text', 'wpautop',            30 );

In a nutshell it is reasonably trustworthy, having been scrubbed on submissions and coming back from database.

Leave a Reply

Your email address will not be published. Required fields are marked *