Disable Comments & Delete All Comments <= 1.3.0 - Missing Authorization
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:NTechnical Details
What Changed in the Fix
Changes introduced in v1.3.1
Source Code
WordPress.org SVNThis 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
POSTrequest containing deletion parameters. - Required Role: Subscriber or higher (Authenticated).
- Vulnerable Parameter:
wbcr_cmp_post_types[]and a trigger parameter (likelywbcr_cmp_delete_commentsorwbcr_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
- The plugin registers an admin page via the "Webcraftic Factory" framework.
- The class
WbcrCmp_DeleteCommentsPage(extendingWbcr_FactoryPages480_AdminPage) handles the "Delete Comments" interface. - When a request is made to
wp-admin/admin.php?page=delete_comments-comments-plus, theadmin_inithook (or a framework-specific equivalent) triggers the page's processing logic. - In version 1.3.0, the logic that processes the
POSTrequest to delete comments (likely in anexecute()orsave()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. - Because
admin_initruns for all authenticated users (including Subscribers visitingadmin-ajax.phpor 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.
- 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. - JS Localization: Check for variables registered via
wp_localize_script. - Strategy:
- Login as a Subscriber.
- Navigate to
wp-admin/index.php. - Use
browser_evalto search for nonces in the globalwindowobject or within script tags. - Target Variable: Look for
wbcr_comments_plus_orwbcr_factoryprefixes. - 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:
- Login: Authenticate as a Subscriber user.
- 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(fromgetActionNotices)
- Checkbox names:
- 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]
- Method:
- Execute: Send the request and observe the response. A successful trigger may redirect or return a success notice (look for
wbcr_cmp_clear_comments=1in the redirect URL).
6. Test Data Setup
- 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"
- Create Attacker: Create a user with the Subscriber role.
wp user create attacker attacker@example.com --role=subscriber --user_pass=password123
- Verify Setup: Confirm comments exist using
wp comment list.
7. Expected Results
- The
http_requestshould return a302redirect or a200 OKresponse. - 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
- Database Check: Run
wp comment listvia WP-CLI. If the exploit worked, the list will be empty or missing comments for the targeted post types. - UI Check: Log in as Admin and navigate to Comments. Verify that the count is zero or significantly reduced.
- Log Check: If possible, check the database query log for
DELETE FROM wp_commentscalls triggered during the Subscriber's session.
9. Alternative Approaches
- Action Parameter: If
wbcr_cmp_delete_comments=1fails, try variations based on the framework's standard "save" triggers, such aswbcr_factory_480_save_settings=1oraction=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.
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
@@ -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' ); @@ -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.