First, let me say that there is no web application 100% secure.
That being said, you are using the nonce correctly. The function you are using, update_post_meta()
, will sql-scape the data as it uses insert/update methods of wpdb class. So, there is no risk for most common security problemas.
What you should take care, I think, is data validation, and you are doing that incorrectly. You pass all meta fields values to wp_kses()
function and you allow <a>
elements in all the fields. I think that is not what you want; for example, I think you don’t want to allow <a>
element in the email or phone fields.
Instead of pass all values to wp_kses()
you should do a specific data validation and/or sanitization for each one. For example:
if( isset( $_POST['products_sold'] ) ) {
update_post_meta( $post_id, 'products_sold', sanitize_text_field( $_POST['products_sold'] ) );
}
if( isset( $_POST['website'] ) ) {
//Leave as it was to allow website as <a href="https://wordpress.stackexchange.com/questions/155143/...">...</a>
//update_post_meta( $post_id, 'website', wp_kses( $_POST['website'], $allowed ) );
update_post_meta( $post_id, 'website', esc_url_raw( $_POST['website'] ) );
}
if( isset( $_POST['address'] ) ) {
update_post_meta( $post_id, 'address', sanitize_text_field( $_POST['address'] ) );
}
if( isset( $_POST['phone'] ) ) {
update_post_meta( $post_id, 'phone', sanitize_text_field( $_POST['phone'] ) );
}
if( isset( $_POST['email'] ) ) {
update_post_meta( $post_id, 'email', sanitize_email( $_POST['email'] ) );
}
if( isset( $_POST['hours'] ) ) {
update_post_meta( $post_id, 'hours', sanitize_text_field( $_POST['hours'] ) );
}
You could go further and define a custom validation function that will be performed every time a specific meta field is updated/created. For example:
//Create and define the `sanitize_phone_meta` filter:
add_filter( 'sanitize_post_meta_phone', 'sanitize_phone_meta' );
function ssanitize_phone_meta( $phone ) {
//Perform whatever validation you want for phone value
//For example, if you only want the phone format 000-0000-0000
if(preg_match("/^[0-9]{3}-[0-9]{4}-[0-9]{4}$/", $phone)) {
// $phone is valid
return $phone;
} else {
return false;
}
}
Then, in the save_post
hook:
if( isset( $_POST['phone'] ) ) {
$clean_phone = sanitize_meta( 'phone', $_POST['phone'], 'post' );
if( $clean_phone !== false ) {
update_post_meta( $post_id, 'phone', $clean_phone );
} else {
//Do something when the phone format is not what you expect
}
}
This way, a little more work is required, but the phone meta field will be sanitized against the defined filter every time the phone meta is created/updated from any where without the need of writing the sanitzation code again.
More in: