I want to make sure all of the data in my plugins/themes is handled securely before entering the database and before being output to the browser. My problem is that there are situations where the API handles the sanitization for you -- like when saving post meta fields -- and others where the plugin/theme author is wholly responsible for doing it -- like when saving custom settings.
For the scope of this question, I'm not concerned about validating data at the domain level -- e.g., checking that an Age field on a form is between 0 and 120, or that an e-mail address is valid. I'm only concerned about security -- e.g., escaping SQL queries to avoid SQL injection when saving to the database, or sanitizing data that's output to HTML templates to avoid XSS.
For output sanitization, I know that you always need to use functions like
esc_attr() when echo'ing variables into HTML templates. But, what about when using template tags? Do they all sanitize the output already? If so, for which context (general HTML, tag attributes, etc)? Some functions have variants for different contexts (like
the_title_attribute(), but most don't.
For input sanitization, I know that I need to use
$wpdb->prepare() when making manual queries, but what about when using the Settings API to create a plugin settings page, or saving post meta fields for a custom post type?
Right now I've just been digging through Core and reading tutorials every time I use a function to find out if it sanitizes or not, but that's error-prone and time consuming. I'm hoping to find some kind of comprehensive list of all the possible situations and whether or not the API handles it. e.g.,
- Saving post meta with
- Saving user meta with
- Outputting a post title - use the contextually appropriate variant of
You have to manually validate/sanitize
- Saving plugin options with the Settings API. Pass a callback as the 3rd parameter of
- Direct database queries: Wrap the query in
- Outputting variables in HTML. Use
I'd also be interested to understand why the API provides it in certain situations, but not others. I'm assuming it has something to do with the unknown nature of the data, but would love to hear a thorough explanation.