Securing WordPress Input

By: Ryan Kienstra on: December 31, 2014  in: Security, WordPress VIP

securing input shield

Lessons From The VIP Standards

All data entered on a site should be checked, no mattter who entered it.

Even the administrator could click a malicious link.

There are two methods of securing WordPress input: validation and sanitization.

As with any security issue, use the most restrictive measure you can.

Therefore,

Prefer Validation to Sanitization

Validation only allows a small range of values.

It’s the preferred method for enterprise WordPress VIP sites.

The most restrictive means of validation is called “whitelisting.”

For example, a checkbox might only have values of "1" and "0".

So you can verify that the value is either "1" or "0".

In my plugin Bootstrap Swipe Gallery, I created the function bsg_is_one_or_zero( $value ).

I then used it in the validation callback. You can see it in the full file on GitHub.

function bsg_is_one_or_zero( $value ) {
        return ( '1' == $value ) || ( '0' == $value );
}

Another way to do this is to use a “whitelist” array.

In the example above, I could have checked input against array( '0' , '1' ).

This is more useful if you have a select box, or many options.

The full function would be:

bsg_is_one_or_zero( $value ) {
 	$trusted_values = array( '0' , '1' ); 		     
        return ( in_array( $value , $trusted_values , true ) );
}

As this entry in the codex notes, it’s important to use the argument true as the third argument for in_array.

This forces strict comparison.

Otherwise, the value "1 DROP DATABASE wpDB" would return true.

 

Selected Validation Functions


intval( $value )

  • Returns $value unchanged if it’s an integer.
  • Returns $value as an integer if it’s possible. A string $value of "23" would cause a return of the integer 23.
  • If it’s not possible, returns 0. For example, the argument "foo_string" would cause a return of 0.

absint( $value )

  • Returns $value unchanged if it’s a non-negative integer.
  • If it’s possible, evaluates $value as an integer, and returns its absolute value.
  • Otherwise, returns 0.

is_email( $address )

  • Returns $address if it’s a valid email address.
  • Otherwise, returns false.

Sanitization

When Validation Isn’t Possible

Sometimes, there are too many possible values.

For example, there may be a text input. You should usually use sanitize_text_field.

But use the most restrictive check you can when securing WordPress input.

If you only want urls, use esc_url.

In my “Adapter” theme, I used esc_url to sanitize a url passed to a filter.

This ensures that it has the right protocol (http, https, etc.). And no mailicious characters.

You can see the full file on GitHub.

add_action( 'after_setup_theme' , 'awp_editor_styles' );
function awp_editor_styles() {
        $style_path = apply_filters( 'awp_editor_style_path' , '' );
        if ( $style_path ) {
                add_editor_style( esc_url( $style_path ) );
        }
}

See more sanitization functions in the WordPress Codex. Most of them start with sanitize_ , like sanitize_html_class.

Code Reviews

Checking Your Work

It’s hard to always use the right function, and the stakes are high.

Having someone else review your code is almost necessary.

Weston Ruter was kind enough to do a review of my “Adapter” theme. He found some security issues.

All themes and plugins on wordpress.org are reviewed, as well.

Securing WordPress Input

By applying these guidelines, along with a reviewer, you’ll have a safer site.

What are your approaches to securing input?

Have your written custom functions for this?

Add your comment below.

  • This field is for validation purposes and should be left unchanged.

Leave a comment

Get Free Updates

  • This field is for validation purposes and should be left unchanged.