Skip to content

Fixing errors for input data

Anisur Rahman edited this page Aug 23, 2023 · 10 revisions

There are several different sniffs that will flag code that uses input data (the $_POST, $_GET, and $_REQUEST superglobal variables, etc.). This page explains what these errors mean, and gives some examples of how to fix them.

Validation

If you have the following code:

if ( 'Yes' === $_POST['auth_step'] ) { // ...

You'll get an error about a non-validated input variable. You might get the following errors:

 WARNING | Detected access of super global var $_POST,probably need manual inspection.
 ERROR   | Detected usage of a non-validated input variable: $_POST 

Our focus right now is that "non-validated input variable" error. What does that mean?

WordPressCS is asking you to validate that the auth_step key even exists in the $_POST array. To fix that error, you'd modify your code to look like this:

if ( isset( $_POST['auth_step'] ) && 'Yes' === $_POST['auth_step'] ) { // ...

Any time that you are accessing input data, you need to first validate that the data you want was really included in the request. That's what this error is for.

In addition to isset() you could also use empty() to validate the data. That allows you to check that the value is sent and isn't empty at the same time:

if ( ! empty( $_POST['auth_step'] ) && 'Yes' === $_POST['auth_step'] ) { // ...

This is sometimes useful.

Slashing

Let's look at another example:

if ( isset( $_POST['foo'] ) ) {
    $foo = $_POST['foo']; // ...

In this example we are properly validating that the foo key is set in the $_POST array before attempting to access it. But we'll likely get these other errors:

ERROR   | Detected usage of a non-sanitized input variable: $_POST 
ERROR   | Missing wp_unslash() before sanitization.

Let's look at that second error first. WordPressCS is asking us to pass the input data through wp_unslash(). Why is this necessary? Because WordPress "magic-quotes" all of the input superglobals ($_GET, $_POST, etc.). Any time there is a quote mark (' or ") in an input string, it is "escaped" with a backslash: \' or \". So if you had a string like That's cool, it would be slashed, turning it into That\'s cool. To undo WordPress's slashing, we need to use wp_unslash() to remove any slashes that it added to the user input. Otherwise, when the data is saved to the database and then later pulled back out of the database and displayed, it will have those extra slashes in it.

It is strange, I know. See #172 and core tickets #24106 and #18322.

To fix this error, we need to unslash the input data before using it, like this:

if ( isset( $_POST['foo'] ) ) {
    $foo = wp_unslash( $_POST['foo'] ); // ...

Sanitization

This still leaves us with our other error though:

ERROR   | Detected usage of a non-sanitized input variable: $_POST 

Now we need to fix that. What WordPressCS is asking us to do is sanitize the input data before we use it. Exactly how that is done will depend on the type of data that $_POST['foo'] is. If it is a URL, we would use sanitize_url() to sanitize it. If it is an email address, we'd use sanitize_email(). If it is a generic string of text, we'd use sanitize_text_field(), like this:

if ( isset( $_POST['foo'] ) ) {
    $foo = sanitize_text_field( wp_unslash( $_POST['foo'] ) ); // ...

It is also possible that the input data could be a complex array structure. For more information on how to deal with that, see our wiki page on sanitizing array input data.

For a complete list of sanitizing functions which WordPressCS recognizes, check WordPressCS\WordPress\Helpers\SanitizationHelperTrait::$sanitizingFunctions. You can also check the WordPress Common APIs handbook for more information.

Nonces

In all of the above examples, you'll probably also encounter another error:

 ERROR   | Processing form data without nonce verification 

WordPressCS is telling you that you are processing input data without using a nonce to guard against CSRF.

Let's take our previous example, and assume that you've added a nonce to the request, that will end up in $_POST['foo_nonce']. We'd verify that nonce like this:

if (
    isset( $_POST['foo'], $_POST['foo_nonce'] ) 
    && wp_verify_nonce( sanitize_key( $_POST['foo_nonce'] ), 'foo_action' )
) {
    $foo = sanitize_text_field( wp_unslash( $_POST['foo'] ) ); // ...

This will fix the error.

There are a few things that you should take note of:

  • We need to validate $_POST['foo_nonce'] just like any other input data.
  • It also needs to be sanitized, since wp_verify_nonce() is a pluggable function, and so it isn't considered a sanitizing function itself.
  • Since a nonce will only include alpha-numeric characters, we use sanitize_key() to sanitize it. Because sanitize_key() will automatically strip out any quotes or slashes, WordPressCS will know that wp_unslash() isn't needed in this case, and won't report a slashing error.