Validating, Sanitizing, and Escaping User Data in WordPress Development

Never trust user-provided data. That principle is one of the foundations of secure web development. In WordPress themes, plugins, and other web applications, there are three basic steps that help keep user data handling safe.

  • Validate user input before processing it so the data matches the format you expect.
  • Sanitize user input before saving it to the database so unexpected values do not create bugs or security problems.
  • Escape user data when outputting it so special characters do not break the page or create security issues.

Validate user data before processing it

Validation is about checking whether the submitted data matches the type of value your code expects. WordPress provides several helper functions for this, and the correct choice depends on the data type you are validating.

Suppose your form contains the following field:

<input type="text" id="zipcode" name="zipcode" maxlength="5" />

That field limits the length to five characters in the browser, but it does not prevent a user from typing letters instead of numbers. A postal code should contain numeric data, so server-side validation is still required.

One way to validate that field on the server is:

$safe_zipcode = intval( $_POST['zipcode'] );
if ( ! $safe_zipcode ) {
    $safe_zipcode = '';
}

if ( strlen( $safe_zipcode ) > 5 ) {
    $safe_zipcode = substr( $safe_zipcode, 0, 5 );
}

update_post_meta( $post->ID, 'zipcode', $safe_zipcode );

The browser-side maxlength attribute is not enough on its own. Some browsers ignore it, and users can bypass client-side checks anyway, so validation still needs to happen on the server.

intval() forces the submitted value to become an integer. If the input is not numeric, the result becomes 0, which makes it easy to detect invalid data.

This is very close to the WordPress white-list mindset: only allow the kind of input you actually expect.

Sanitize user data before saving it

Sanitizing is more flexible than validation. When the exact input format is less strict, sanitization helps clean the value before it is stored.

For example, suppose your form contains this field:

<input type="text" id="title" name="title" />

You can sanitize that input with sanitize_text_field():

$title = sanitize_text_field( $_POST['title'] );
update_post_meta( $post->ID, 'title', $title );

Behind the scenes, that function does several useful things:

  • Checks for invalid UTF-8 with wp_check_invalid_utf8().
  • Converts a lone < character to an HTML entity.
  • Removes all tags.
  • Removes line breaks, tabs, and extra whitespace.
  • Strips octets.

WordPress also includes many other sanitization helpers, including:

  • sanitize_email() — remove invalid characters from an email address.
  • sanitize_file_name() — remove invalid characters from a file name.
  • sanitize_html_class() — clean an HTML class name so it contains only valid characters.
  • sanitize_key() — clean characters that should not be used in a key.
  • sanitize_meta() — sanitize values used in meta fields.
  • sanitize_mime_type() — sanitize a MIME type string.
  • sanitize_option() — sanitize option values according to the option being stored.
  • sanitize_sql_orderby() — sanitize an SQL ORDER BY clause.
  • sanitize_text_field() — sanitize plain text input.
  • sanitize_textarea_field() — sanitize plain text input while preserving line breaks.
  • sanitize_title() — sanitize data for use in a slug.
  • sanitize_title_for_query() — sanitize a slug-like value for query context.
  • sanitize_title_with_dashes() — sanitize a title and replace spaces with dashes.
  • sanitize_user() — sanitize a value for use as a WordPress username.

Escape user data when outputting it

Even sanitized data still needs to be escaped when it is rendered. WordPress provides different escaping helpers for different output contexts.

esc_html() should be used when outputting text inside HTML elements so unexpected markup does not break the page:

<h4><?php echo esc_html( $title ); ?></h4>

esc_url() should be used when outputting a URL, such as a value used in src or href:

<img src="<?php echo esc_url( $great_user_picture_url ); ?>" />

esc_js() escapes inline JavaScript values:

<a href="#" onclick="<?php echo esc_js( $custom_js ); ?>">Click me</a>

esc_attr() should be used when outputting user-controlled data inside an HTML attribute:

<ul class="<?php echo esc_attr( $stored_class ); ?>">

esc_textarea() escapes text intended for use inside a textarea element:

<textarea><?php echo esc_textarea( $text ); ?></textarea>

Handling user data correctly is one of the basic ways to judge whether a WordPress theme or plugin is well written. Whenever your code accepts user input, think about validation, sanitization, and escaping together. That is how you reduce bugs, prevent security holes, and build more reliable WordPress code.

Related Posts

Leave a Reply

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