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'?


<?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?


<style type="text/css"><?php echo $css; ?></style>
  • From my point of view, allow or not certain HTML tags is data validation, which should be done when data is saved, not when data is displayed. Data should be validated and sanitized always when it is saved, that is rule number 1 on security. – cybmeta May 23 '15 at 9:40
  • Thank for your reply. However, according to this article vip.wordpress.com/2014/06/20/… data should be validated and sanitized always and not only when it's saved but rendered as well. – Michael Khors May 23 '15 at 11:20
  • I totally agree with the article you posted but you need to understand the difference between scaping and data validation/sanitization. As I said, what you are trying to do with the subtitle is data validation: you need to validate the data against valid values and that should be done when the data is saved, using wp_kses seems good. Anyway, if you want to escape only certain HTML tags on data output, I think you need to go with DOM manipulation class. Not sure what to do when printing CSS styles, esc_html could be enough to print CSS rules. – cybmeta May 23 '15 at 11:46

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.

  • As I understand you suggest us just leave it and not to do anything. Am I right? :) – Michael Khors May 23 '15 at 12:51
  • 1
    I am suggesting that if you are sanitizing the particular inputs on save to the same degree as WP does then not escaping them on output is an acceptable practice in my opinion. – Rarst May 23 '15 at 12:54
  • @Rarst that is also my point, sanitizing on save, that is what I was trying to explain in the comments. – cybmeta May 23 '15 at 14:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.