wp_delete_comment takes two tries to delete - then deletes all comments

I'm trying to add a button to my comments that allows a user to delete them.

I have a form declared like so:

form method=post
  input type=submit name=btn-delete value=try-delete
/form

and above it the following php:

?php
  if (isset($_POST[btn-delete])) {
    wp_delete_comment(get_comment_ID(), true);
  }
?

Note this is in my comments.php, and I use the standard API for looping through the comments.

When I click on the button (from the input tag), it reloads the page and does nothing. If I click it again, it deletes all of the comments on the page, rather than just the one comment. How can I fix this?

Thanks in advance.

Topic php comments Wordpress

Category Web


The Insecure Way

You need to change your form so that it includes the ID of the comment you want to delete, e.g.:

<form method="post">
  <input type="hidden" name="comment_id" value="<?php echo get_comment_ID(); ?>" />
  <input type="submit" name="btn-delete" value="try-delete"/>
</form>

Without this, you have no idea which comment the user wanted to delete.

Then, you need to move the code that deletes the comment to a hook in functions.php e.g.:

add_action( 'init', 'i_am_not_safe_to_use' );
function i_am_not_safe_to_use() {
    if ( is_admin() ) {
        return;
    }

    // only run if we're deleting a comment
    if ( empty( $_POST['btn-delete'] ) || empty( $_POST['comment_id'] ) ) {
        return;
    }

    // TODO, security checks

    // delete the comment
    $comment_id = intval( $_POST['comment_id'] );
    wp_delete_comment( $comment_id, true );
}

This will work however it is insecure! Now anybody can delete any comment they want by submitting the form!!!

Security

The code needs to also do the following:

  • check that the user has the necessary capability required to delete that comment
  • add a nonce to the form
  • check the nonce in the hook

At a minimum, you need this check:

if ( current_user_can( 'moderate_comments' ) || current_user_can( 'edit_comment', $comment_id ) ) {
    // then the user has permission to delete the comment
} else {
    wp_die( 'sneaky hackers! You are not allowed to delete this comment' );
}

The REST API

If you send an authenticated DELETE request to the comments REST API at yoursite.com/wp-json/wp/v2/comments/<COMMENT ID GOES HERE> then refresh the page, your comment will be gone.

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.