-
Notifications
You must be signed in to change notification settings - Fork 1
Description
When you include POST/GET/REQUEST/FILE calls in your plugin, it's important to sanitize, validate, and escape them. The goal here is to prevent a user from accidentally sending trash data through the system, as well as protecting them from potential security issues.
SANITIZE: Data that is input (either by a user or automatically) must be sanitized as soon as possible. This lessens the possibility of XSS vulnerabilities and MITM attacks where posted data is subverted.
VALIDATE: All data should be validated, no matter what. Even when you sanitize, remember that you don’t want someone putting in ‘dog’ when the only valid values are numbers.
ESCAPE: Data that is output must be escaped properly when it is echo'd, so it can't hijack admin screens. There are many esc_*() functions you can use to make sure you don't show people the wrong data.
To help you with this, WordPress comes with a number of sanitization and escaping functions. You can read about those here:
https://developer.wordpress.org/apis/security/sanitizing/
https://developer.wordpress.org/apis/security/escaping/
Remember: You must use the most appropriate functions for the context. If you’re sanitizing email, use sanitize_email(), if you’re outputting HTML, use wp_kses_post(), and so on.
An easy mantra here is this:
Sanitize early
Escape Late
Always Validate
Clean everything, check everything, escape everything, and never trust the users to always have input sane data. After all, users come from all walks of life.
Example(s) from your plugin:
includes/class-paybutton-ajax.php:50 $raw_post_data = file_get_contents('php://input');
paybutton.php:58 $_SESSION['pb_paywall_user_wallet_address'] = $_SESSION['cashtab_ecash_address'];
Note: $_SERVER, $_COOKIE and $_SESSION inputs must be sanitized as well.
Although this might be counterintuitive, some or all of its included data can be manipulated by the sender of the request. So it needs to be sanitized just like any other input.
Example(s) from your plugin:
paybutton.php:58 $_SESSION['pb_paywall_user_wallet_address'] = $_SESSION['cashtab_ecash_address'];
Note: There are simple ways to sanitize arrays, in case you need to do so, you can do the following:
- An array of post IDs: array_unique(array_map('absint', $_POST['post_ids']))
- An array of emails: array_map('sanitize_email', $_POST['user_emails'])
- A multidimensional array, being all the elements texts: map_deep( $_POST['arrays_of_texts'], 'sanitize_text_field' )
Sometimes you'll have an array that contains different types of data inside, which would require different types of sanitization.
$sanitized_orders = $_POST['orders']; // Sanitized below.
array_walk_recursive( $sanitized_orders, 'prefix_sanitize_orders' );
function prefix_sanitize_orders( &$item , $key ){
switch ($key){
case 'locator':
$item = sanitize_key($item);
break;
case 'name':
$item = sanitize_text_field($item);
break;
case 'price':
case 'priceDiscounted':
$item = (float)$item;
break;
default:
$item = NULL;
}
}
We have heuristically detected these cases of your plugin that might need array sanitization (might be false positives, please check them out):
paybutton.php:58 $_SESSION['pb_paywall_user_wallet_address'] = $_SESSION['cashtab_ecash_address'];
✔️ You can check this using Plugin Check.