CVE-2026-42749

Disable Comments & Delete All Comments <= 1.3.0 - Missing Authorization

lowMissing Authorization
3.1
CVSS Score
3.1
CVSS Score
low
Severity
1.3.1
Patched in
4d
Time to patch

Description

The Disable Comments & Delete All Comments plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 1.3.0. This makes it possible for authenticated attackers, with Subscriber-level access and above, to perform an unauthorized action.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N
Attack Vector
Network
Attack Complexity
High
Privileges Required
Low
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=1.3.0
PublishedMay 29, 2026
Last updatedJune 2, 2026
Affected plugincomments-plus

What Changed in the Fix

Changes introduced in v1.3.1

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

This plan outlines the steps for a security researcher to demonstrate the Missing Authorization vulnerability in the **Disable Comments & Delete All Comments** plugin (version <= 1.3.0). ### 1. Vulnerability Summary The plugin features a "Delete Comments" tool that allows for bulk deletion of comme…

Show full research plan

This plan outlines the steps for a security researcher to demonstrate the Missing Authorization vulnerability in the Disable Comments & Delete All Comments plugin (version <= 1.3.0).

1. Vulnerability Summary

The plugin features a "Delete Comments" tool that allows for bulk deletion of comments by post type or status. The logic for processing this deletion is implemented within the WbcrCmp_DeleteCommentsPage class (in admin/pages/class-page-delete-comments.php). Although the admin page itself is intended for administrators, the underlying request processing logic lacks an explicit capability check (e.g., current_user_can( 'manage_options' )).

Consequently, an authenticated user with Subscriber-level permissions can trigger the deletion logic by sending a specifically crafted POST request to the admin area, leading to unauthorized modification of the site's database (loss of comments).

2. Attack Vector Analysis

  • Endpoint: wp-admin/admin.php?page=delete_comments-comments-plus
  • Action/Trigger: A POST request containing deletion parameters.
  • Required Role: Subscriber or higher (Authenticated).
  • Vulnerable Parameter: wbcr_cmp_post_types[] and a trigger parameter (likely wbcr_cmp_delete_comments or wbcr_cmp_clear_comments).
  • Authentication: Required (Subscriber credentials).
  • Preconditions: The plugin must be active, and there must be comments present on the site to observe the impact.

3. Code Flow

  1. The plugin registers an admin page via the "Webcraftic Factory" framework.
  2. The class WbcrCmp_DeleteCommentsPage (extending Wbcr_FactoryPages480_AdminPage) handles the "Delete Comments" interface.
  3. When a request is made to wp-admin/admin.php?page=delete_comments-comments-plus, the admin_init hook (or a framework-specific equivalent) triggers the page's processing logic.
  4. In version 1.3.0, the logic that processes the POST request to delete comments (likely in an execute() or save() method not fully visible in the snippet but standard for the framework) verifies the CSRF nonce but fails to verify that the user has the necessary administrative capabilities.
  5. Because admin_init runs for all authenticated users (including Subscribers visiting admin-ajax.php or the dashboard), the deletion logic executes before WordPress core's page-level capability check blocks access to the UI.

4. Nonce Acquisition Strategy

The CVSS "Access Complexity: High" indicates that a valid WordPress nonce is likely required. Since a Subscriber cannot access the "Delete Comments" page directly, they must obtain a nonce from another source.

  1. Dashboard Widget / Ads: The plugin registers a dashboard widget and advertisements ('subscribe_widget' => true, 'render_adverts' => true). These components are often rendered for all logged-in users, including Subscribers.
  2. JS Localization: Check for variables registered via wp_localize_script.
  3. Strategy:
    • Login as a Subscriber.
    • Navigate to wp-admin/index.php.
    • Use browser_eval to search for nonces in the global window object or within script tags.
    • Target Variable: Look for wbcr_comments_plus_ or wbcr_factory prefixes.
    • If no specific nonce is found, attempt the exploit without one or use a nonce from a different Webcraftic plugin component (the framework often uses a generic nonce for admin actions).

5. Exploitation Strategy

Perform the following steps using the http_request tool:

  1. Login: Authenticate as a Subscriber user.
  2. Parameter Identification: Based on the source code:
    • Checkbox names: wbcr_cmp_post_types[]
    • Post type values: post, page, attachment, etc.
    • Success condition: wbcr_cmp_clear_comments=1 (from getActionNotices)
  3. Craft Request:
    • Method: POST
    • URL: http://[target]/wp-admin/admin.php?page=delete_comments-comments-plus
    • Headers: Content-Type: application/x-www-form-urlencoded
    • Body:
      wbcr_cmp_post_types[]=post&wbcr_cmp_delete_comments=1&wbcr_cmp_clear_comments=1&_wpnonce=[NONCE]
      
  4. Execute: Send the request and observe the response. A successful trigger may redirect or return a success notice (look for wbcr_cmp_clear_comments=1 in the redirect URL).

6. Test Data Setup

  1. Create Comments: Use WP-CLI to create several comments on various posts.
    • wp comment create --comment_post_ID=1 --comment_content="Test Comment 1"
    • wp comment create --comment_post_ID=1 --comment_content="Test Comment 2"
  2. Create Attacker: Create a user with the Subscriber role.
    • wp user create attacker attacker@example.com --role=subscriber --user_pass=password123
  3. Verify Setup: Confirm comments exist using wp comment list.

7. Expected Results

  • The http_request should return a 302 redirect or a 200 OK response.
  • The redirect URL should contain wbcr_cmp_clear_comments=1, which the plugin uses to display the success message: "All comments have been deleted."
  • The actual comments in the database for the specified post types should be permanently removed.

8. Verification Steps

  1. Database Check: Run wp comment list via WP-CLI. If the exploit worked, the list will be empty or missing comments for the targeted post types.
  2. UI Check: Log in as Admin and navigate to Comments. Verify that the count is zero or significantly reduced.
  3. Log Check: If possible, check the database query log for DELETE FROM wp_comments calls triggered during the Subscriber's session.

9. Alternative Approaches

  • Action Parameter: If wbcr_cmp_delete_comments=1 fails, try variations based on the framework's standard "save" triggers, such as wbcr_factory_480_save_settings=1 or action=wbcr_comments_plus_delete.
  • Direct Post Types: Try omitting the wbcr_cmp_post_types[] array to see if the plugin defaults to deleting all comments when the parameter is missing but the trigger is present.
  • Generic Nonce: If a specific deletion nonce isn't found, try using any nonce generated by the "Factory" framework found on the dashboard.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Disable Comments & Delete All Comments plugin for WordPress is vulnerable to unauthorized comment deletion due to missing capability checks in the WbcrCmp_DeleteCommentsPage class and its underlying admin framework. This allows authenticated attackers with Subscriber-level access to trigger bulk deletion of comments, spam, or trashed items by sending crafted POST requests to the plugin's administrative processing logic.

Vulnerable Code

// admin/pages/class-page-delete-comments.php around line 386
	/**
	 * This action deletes all comments from the database without restoring.
	 */
	public function deleteAllCommentsAction() {
		check_admin_referer( $this->getResultId() . '_delete_all_comments' );

		if ( isset( $_POST['wbcr_cmp_delete_all'] ) ) {

---

// admin/pages/class-page-delete-comments.php around line 481
	/**
	 * This action deletes spam comments
	 */
	public function deleteSpamCommentsAction() {
		check_admin_referer( $this->getResultId() . '_delete_spam_comments' );

		$this->deleteComments( 'spam' );
	}

---

// libs/factory/pages/includes/admin-page.class.php around line 338 in version 1.3.0
			// makes redirect to the page
			$controller = $this->request->get('fy_page', null, true);

			if( !empty($controller) ) {
				$this->executeController($controller);
			}

			$action = $this->request->get('fy_action', null, true);

			if( !empty($action) ) {
				$result_id = $this->getResultId();
				$this->executeAction($action);
			}

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/comments-plus/1.3.0/admin/pages/class-page-delete-comments.php /home/deploy/wp-safety.org/data/plugin-versions/comments-plus/1.3.1/admin/pages/class-page-delete-comments.php
--- /home/deploy/wp-safety.org/data/plugin-versions/comments-plus/1.3.0/admin/pages/class-page-delete-comments.php	2026-01-12 14:53:50.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/comments-plus/1.3.1/admin/pages/class-page-delete-comments.php	2026-04-30 11:19:20.000000000 +0000
@@ -386,6 +386,9 @@
 	 * This action deletes all comments from the database without restoring.
 	 */
 	public function deleteAllCommentsAction() {
+		if ( ! current_user_can( $this->capabilitiy ) ) {
+			return;
+		}
 		check_admin_referer( $this->getResultId() . '_delete_all_comments' );
 
 		if ( isset( $_POST['wbcr_cmp_delete_all'] ) ) {
@@ -481,6 +484,9 @@
 	 * This action deletes spam comments
 	 */
 	public function deleteSpamCommentsAction() {
+		if ( ! current_user_can( $this->capabilitiy ) ) {
+			return;
+		}
 		check_admin_referer( $this->getResultId() . '_delete_spam_comments' );
 
 		$this->deleteComments( 'spam' );
@@ -490,6 +496,9 @@
 	 * This action deletes unaproved comments
 	 */
 	public function deleteUnaprovedCommentsAction() {
+		if ( ! current_user_can( $this->capabilitiy ) ) {
+			return;
+		}
 		check_admin_referer( $this->getResultId() . '_delete_unaproved_comments' );
 
 		$this->deleteComments();
@@ -499,6 +508,9 @@
 	 * This action deletes trash comments
 	 */
 	public function deleteTrashCommentsAction() {
+		if ( ! current_user_can( $this->capabilitiy ) ) {
+			return;
+		}
 		check_admin_referer( $this->getResultId() . '_delete_trash_comments' );
 
 		$this->deleteComments( 'trash' );
diff -ru /home/deploy/wp-safety.org/data/plugin-versions/comments-plus/1.3.0/libs/factory/pages/includes/admin-page.class.php /home/deploy/wp-safety.org/data/plugin-versions/comments-plus/1.3.1/libs/factory/pages/includes/admin-page.class.php
--- /home/deploy/wp-safety.org/data/plugin-versions/comments-plus/1.3.0/libs/factory/pages/includes/admin-page.class.php	2024-12-10 00:10:16.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/comments-plus/1.3.1/libs/factory/pages/includes/admin-page.class.php	2026-04-30 11:19:20.000000000 +0000
@@ -338,6 +338,27 @@
 				$this->menu_post_type = null;
 			}
 
+			// if this page for a custom menu page
+			if( $this->menu_post_type ) {
+				$this->menu_target = 'edit.php?post_type=' . $this->menu_post_type;
+
+				if( empty($this->capabilitiy) ) {
+					$post_type_object = get_post_type_object($this->menu_post_type);
+
+ 					if( $post_type_object && isset( $post_type_object->cap ) && ! empty( $post_type_object->cap->edit_posts ) ) {
+ 						$this->capabilitiy = $post_type_object->cap->edit_posts;
+ 					}
+				}
+			}
+
+			// sets default capabilities
+			if( empty($this->capabilitiy) ) {
+				$this->capabilitiy = 'manage_options';
+			}
+
+			if ( ! current_user_can( $this->capabilitiy ) ) {
+				return;
+			}
 			// makes redirect to the page
 			$controller = $this->request->get('fy_page', null, true);

Exploit Outline

The exploit methodology involves bypassing intended administrative restrictions by exploiting missing capability checks in the plugin's action processing logic. 1. Authentication: An attacker must be authenticated with at least Subscriber-level privileges. 2. Nonce Acquisition: The attacker must obtain a valid WordPress nonce for the deletion actions (e.g., `delete_comments-comments-plus_delete_all_comments`). These nonces are frequently leaked in the WordPress dashboard source code due to the plugin's dashboard widgets and script localizations. 3. Payload Construction: The attacker crafts a POST request to `wp-admin/admin.php?page=delete_comments-comments-plus` containing the trigger parameters for deletion (such as `wbcr_cmp_delete_all=1` or `wbcr_cmp_post_types[]=post`) and the retrieved nonce. 4. Execution: Because the plugin's backend logic in `WbcrCmp_DeleteCommentsPage` executes before capability checks and does not perform its own `current_user_can()` validation, the server processes the deletion request regardless of the user's role, resulting in unauthorized data loss.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.