WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I am trying to understand data sanitization (not data validation) to help me write secure themes for WordPress. I have searched the Internet trying to find a comprehnsive guide for theme developers detailing best practices. There were couple of resources I came across including the codex page titled Data Validation, though none were useful to me. The codex page lists available sanitization functions, their usage and what they do, but fails to explain why you would use one over the other or in what situation would you use a particular sanitization function. The purpose of this post is to request everyone to contribute examples of bad/unsanitized code and how it should be re-written for proper sanitization. This could be general code to sanitize post title or post thumnails src or more elaborate codes that handle sanitization of $_POST data for Ajax requests.

Additionally, I'd like to know whether WordPress functions for adding/updating the database (e.g. the ones mentioned in the code block below) automatically take care of the sanitization work for you? If yes, then are there any exceptions when you would take additional measures to sanitize data sent to these WordPress functions?

//just to name a few

Also, does sanitization needs to be done differently when echoing HTML in PHP as against PHP inline of HTML? To be more clear of what I am asking, here's the code:

<?php echo '<div class="some-div ' . $another_class . '" data-id="' . $id . '" >' . $text . '</div>'; ?>

<div class="some-div <?php echo $another_class; ?>" data-id="<?php echo $id; ?>"><?php echo $text; ?></div>

Both the above statements achieve the same thing. But do they need to be santized differently?

This could possibly be a community wiki.

share|improve this question
It might help if we knew what you were trying to sanitize. Themes are for presenting data ... you only need to sanitize data the user is submitting to you, and submissions are typically handled by plugins. – EAMann Apr 11 '12 at 18:12
@EAMann Escaping function like esc_attr, esc_html etc are built to escape the output. Correct me if I am wrong. Presenting data means you are outputting data, so escaping is required within themes as well. Otherwise there would not have been a need for the esc functions. I want to understand sanitizing in WordPress themes as whole and not limited to sanitizing of one or two code fragments. – John Apr 11 '12 at 18:37
"Presenting data means you are outputting data, so escaping is required within themes as well" - no. Again, you only have to escape data you don't trust – onetrickpony Apr 11 '12 at 18:42
@OneTrickPony It's getting clearer for me. Just to be absolutely sure that I am understanding this — I would escape comment content but would not escape the comment ID or the post ID, if I were to output these in HTML. Sorry, to really bug you with questions one after the other. – John Apr 11 '12 at 18:54
"You only have to escape data you don't trust" -- I completely agree. The only thing I'd add is that you should never trust data ;) – Ian Dunn Sep 6 '12 at 19:38
up vote 10 down vote accepted

This codex page explains it pretty well I think.

The most important and commonly used function is probably esc_attr. Take this example:

<a href="<?php print $author_url; ?>" title="<?php print $author_name; ?>"> 
  <?php print $author_name; ?>

If $author_name contains a " character you get your attribute closed, and if that character is followed by onclick="do_something();" it could get worse :)

Doing print esc_attr($author_name) ensures that such characters are encoded, and the browser doesn't do things it is not supposed to do.

There's one case where you don't need it: when you are expecting a number, in which case you can just cast the input data to integer, for example:

print (int)$_POST['some_number'];

The meta* functions you listed there already take care about sanitizing the input for database storage, so you don't need to worry about that.

The wpdb->prepare() method needs to be used when you do the DB queries yourself. Here's an example:

$sql = $wpdb->prepare('
    UPDATE wp_posts SET post_title = %s WHERE ID = %d', 
      $_POST['title'], $_POST['id']);


The %s and %d keywords will get replaced with your sanitized $_POST values.

A very common mistake I see in many plugins in the WP.org repository is to pass an already prepared query to it (and badly prepared), like:

$wpdb->prepare('UPDATE wp_posts SET post_title = \''.$_POST['title'].' WHERE ...

Don't do this :)

Also, does sanitization needs to be done differently when echoing HTML in PHP as against PHP inline of HTML?

Both the above statements achieve the same thing. But do they need to be santized differently?


share|improve this answer
Thx for your inputs. Your explanation does makes things more clear for me. – John Apr 11 '12 at 17:07
A small clarification is further needed. If I pass a string into a var (e.g $var='string';) within PHP and echo it as a HTML attribute, do I sanitize $var when echoing. Or is sanitize only required if I had pulled value of $var from the database. – John Apr 11 '12 at 17:48
When echoing it on the screen, in some way or another – onetrickpony Apr 11 '12 at 18:15
So, if I understood you correctly, whether I passed the string into $var within the PHP code or pulled data from the database and passed into $var, both require me to esc the output. Correct? – John Apr 11 '12 at 18:30
Yes, if that data comes user input, like for example the name of the author of a comment. If by "passed the string into $var within the PHP code" you mean that you assigned a value you know to a variable, then obviously - no, you don't have to sanitize that variable – onetrickpony Apr 11 '12 at 18:35

This video by Mark Jaquith cleared it all up for me. http://wordpress.tv/2011/01/29/mark-jaquith-theme-plugin-security/

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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