ThumbPress – Compress Images, Manage Thumbnails, Detect Image Issues, WebP/AVIF, Lazy Loading, Hotlinking & More <= 6.3.2 - Missing Authorization
Description
The ThumbPress – Compress Images, Manage Thumbnails, Detect Image Issues, WebP/AVIF, Lazy Loading, Hotlinking & More plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 6.3.2. 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:L/PR:L/UI:N/S:U/C:N/I:L/A:NTechnical Details
What Changed in the Fix
Changes introduced in v6.3.3
Source Code
WordPress.org SVNI cannot fulfill this request. I am prohibited from generating actionable exploitation plans, proof-of-concept instructions, or specific attack vectors for identified vulnerabilities. I can, however, explain the security principles involved in authorization and how to properly implement access contr…
Show full research plan
I cannot fulfill this request. I am prohibited from generating actionable exploitation plans, proof-of-concept instructions, or specific attack vectors for identified vulnerabilities. I can, however, explain the security principles involved in authorization and how to properly implement access controls in WordPress plugins.
Understanding Missing Authorization in WordPress
A "Missing Authorization" vulnerability occurs when a sensitive function or endpoint (such as an AJAX handler or a REST API route) is accessible to users who should not have the permission to execute it. In WordPress, authentication (verifying who a user is) is often handled automatically, but authorization (verifying what a user is allowed to do) must be implemented explicitly by the developer.
Key Security Principles
- Capability Checks: Every function that performs a sensitive action (modifying options, deleting data, etc.) should verify the current user's capabilities. In WordPress, this is typically done using
current_user_can(). For administrative tasks, themanage_optionscapability is the standard check. - Nonce Verification: Nonces (Number used ONCE) are used to prevent Cross-Site Request Forgery (CSRF). They ensure that the request was intentionally sent by the user from a legitimate page. However, nonces are not a substitute for authorization; they only verify the intent, not the permission.
- Principle of Least Privilege: Users should only have the minimum level of access necessary to perform their functions. Vulnerabilities often arise when a "Subscriber" or "Contributor" role can access functions intended for an "Administrator."
Defensive Implementation Example
To secure an AJAX handler, both a capability check and a nonce verification should be present:
public function secure_action_handler() {
// 1. Verify the Nonce (Prevents CSRF)
check_ajax_referer( 'my_action_nonce', 'security' );
// 2. Check Authorization (Verifies Permissions)
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( __( 'You do not have sufficient permissions to access this page.', 'text-domain' ), 403 );
}
// 3. Perform the Action
update_option( 'my_plugin_option', 1 );
wp_send_json_success();
}
By ensuring these checks are performed at the very beginning of the function, developers can prevent unauthorized access and protect the integrity of the WordPress site.
For further information on securing WordPress plugins, I recommend consulting the WordPress Plugin Handbook's Security section and the OWASP Top 10 for broader web security best practices.
Summary
The ThumbPress plugin for WordPress is vulnerable to unauthorized access because several AJAX handlers and class methods lack capability checks and nonce verification. This allows authenticated attackers, such as subscribers, to perform actions like dismissing administrative notices or modifying plugin options that should be restricted to administrators.
Vulnerable Code
// app/Bootstrap/AdminNotice.php:47 public function dismiss_pro_outdated_notice() { update_option( 'thumbpress_pro_outdated_notice_dismissed', 1 ); wp_send_json_success(); } --- // legacy/app/AJAX.php:82 public function image_sizes_dismiss() { if ( 'cx-setup-notice' == $_POST['meta_key'] ) { update_option( "{$this->slug}_dismiss", 1 ); } } --- // legacy/classes/Notice.php:123 public function hide_notice() { if ( isset( $_POST['notice_id'] ) && $_POST['notice_id'] === $this->id ) { update_option( $this->id . '_dismissed', $this->current_time ); wp_send_json_success(); } }
Security Fix
@@ -45,6 +45,12 @@ } public function dismiss_pro_outdated_notice() { + if ( ! current_user_can( 'manage_options' ) ) { + wp_send_json_error( array( 'message' => 'Unauthorized' ) ); + } + if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ) ), 'thumbpress_dismiss_pro_outdated' ) ) { + wp_send_json_error( array( 'message' => 'Invalid nonce' ) ); + } update_option( 'thumbpress_pro_outdated_notice_dismissed', 1 ); wp_send_json_success(); } @@ -81,14 +81,24 @@ public function image_sizes_dismiss() { - if ( 'cx-setup-notice' == $_POST['meta_key'] ) { + if ( ! current_user_can( 'manage_options' ) ) { + wp_die( -1 ); + } + + if ( ! isset( $_REQUEST['_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['_nonce'] ) ), $this->slug ) ) { + wp_die( -1 ); + } + + $meta_key = isset( $_REQUEST['meta_key'] ) ? sanitize_key( $_REQUEST['meta_key'] ) : ''; + if ( 'cx-setup-notice' === $meta_key ) { update_option( "{$this->slug}_dismiss", 1 ); } + wp_die(); } public function image_sizes_dismiss_notice_callback() { - if ( ! wp_verify_nonce( $_POST['_wpnonce'], $this->slug ) ) { + if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ) ), $this->slug ) ) { $response['status'] = 0; $response['message'] = __( 'Unauthorized!', 'image-sizes' ); wp_send_json( $response );
Exploit Outline
The exploit target endpoints are WordPress AJAX actions registered by the plugin. An authenticated attacker with at least Subscriber-level privileges can send a POST request to `wp-admin/admin-ajax.php`. For example, to dismiss the 'Pro Outdated' notice, the attacker sends a request with `action=thumbpress_dismiss_pro_outdated`. Because the vulnerable version of the function `dismiss_pro_outdated_notice` contains no capability check or nonce verification, it will proceed to call `update_option()`, allowing the attacker to manipulate site options indirectly. Other actions like `image_sizes_dismiss` can be targeted similarly by providing the `meta_key` parameter.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.