📢 Calling all Vulnerability Researchers and Bug Bounty Hunters! 📢
🌞 Spring into Summer with Wordfence! Now through September 4, 2025, earn 2X bounty rewards for all in-scope submissions from our ‘High Threat’ list in software with fewer than 5 million active installs. Bounties up to $31,200 per vulnerability. Submit bold. Earn big!
💉 Participate in the SQLsplorer Challenge! Now through September 22, 2025, all SQL Injection vulnerabilities in software with at least 25 active installs are considered in-scope for all researchers, regardless of researcher tier AND earn a 20% bonus on all SQL Injection vulnerability submissions.
On June 5th, 2025, we received a submission for a Privilege Escalation vulnerability in Dokan Pro, a WordPress plugin with more than 15,000 sales. This vulnerability makes it possible for an authenticated attacker, with vendor-level permission, to change the password of any user, including an administrator, which allows them to take over the account and the website.
Props to Foxyyy who discovered and responsibly reported this vulnerability through the Wordfence Bug Bounty Program. This researcher earned a bounty of $966.00 for this discovery. Our mission is to secure WordPress through defense in depth, which is why we are investing in quality vulnerability research and collaborating with researchers of this caliber through our Bug Bounty Program. We are committed to making the WordPress ecosystem more secure through the detection and prevention of vulnerabilities, which is a critical element to the multi-layered approach to security.
Wordfence Premium, Wordfence Care, and Wordfence Response users received a firewall rule to protect against any exploits targeting this vulnerability on June 10, 2025. Sites using the free version of Wordfence received the same protection 30 days later on July 10, 2025.
We contacted the Dokan team on June 9, 2025, and they registered on our Wordfence Vulnerability Management Portal for WordPress vendors on June 12, 2025. After receiving the full disclosure details instantly through the portal, the developer released the patch on August 6, 2025.
We urge users to update their sites with the latest patched version of Dokan Pro, version 4.0.6 at the time of this writing, as soon as possible.
Vulnerability Summary from Wordfence Intelligence
Technical Analysis
Dokan Pro is a WordPress and WooCommerce multivendor marketplace plugin, which includes many premium features and functions.
By default, the plugin allows customers to become vendors as the primary purpose of the plugin is to enable vendors to sell through their own marketplaces on a WordPress site. Once registered, vendors can manage their store through the vendor dashboard. From there, they can manage products, manage orders, and they can add staff users who will have access to their store. Unfortunately, this functionality was insecurely implemented.
Examining the code reveals that the plugin uses the handle_staff()
function in the Dokan_Staffs
class to handle staff user creation or modification.
public function handle_staff() { $post_data = wp_unslash( $_POST ); if ( ! isset( $post_data['staff_creation'] ) ) { return; } if ( ! wp_verify_nonce( $post_data['vendor_staff_nonce_field'], 'vendor_staff_nonce' ) ) { return; } $is_edit = ! empty( $post_data['staff_id'] ) ? $post_data['staff_id'] : false; $user_password = ''; if ( empty( $post_data['first_name'] ) ) { self::$errors[] = new WP_Error( 'no-first-name', __( 'First Name must be required', 'dokan' ) ); } if ( empty( $post_data['last_name'] ) ) { self::$errors[] = new WP_Error( 'no-last-name', __( 'Last Name must be required', 'dokan' ) ); } if ( empty( $post_data['email'] ) ) { self::$errors[] = new WP_Error( 'no-email', __( 'Email must be required', 'dokan' ) ); } if ( empty( $post_data['vendor_id'] ) ) { self::$errors[] = new WP_Error( 'no-vendor', __( 'No vendor found for assigning this staff', 'dokan' ) ); } if ( ! empty( $post_data['staff_id'] ) ) { if ( ! empty( $post_data['password'] ) ) { $user_password = $post_data['password']; } } if ( ! $is_edit ) { $userdata = array( 'user_email' => $post_data['email'], 'user_pass' => wp_generate_password(), 'user_login' => $post_data['email'], 'first_name' => sanitize_text_field( $post_data['first_name'] ), 'last_name' => sanitize_text_field( $post_data['last_name'] ), 'role' => 'vendor_staff', 'display_name' => sanitize_text_field( $post_data['first_name'] ) . ' ' . sanitize_text_field( $post_data['last_name'] ), ); } else { $userdata = array( 'ID' => (int) $is_edit, 'user_email' => $post_data['email'], 'user_login' => $post_data['email'], 'first_name' => sanitize_text_field( $post_data['first_name'] ), 'last_name' => sanitize_text_field( $post_data['last_name'] ), 'role' => 'vendor_staff', 'display_name' => sanitize_text_field( $post_data['first_name'] ) . ' ' . sanitize_text_field( $post_data['last_name'] ), ); if ( ! empty( $user_password ) ) { $userdata['user_pass'] = wp_hash_password( $user_password ); } } $user = wp_insert_user( $userdata ); if ( is_wp_error( $user ) ) { self::$errors[] = $user; return; } if ( ! $is_edit ) { do_action( 'dokan_new_staff_created', $user ); } elseif ( ! empty( $user_password ) ) { WC_Emails::instance()->get_emails()['Dokan_Staff_Password_Update']->trigger( $user ); } $staff = new WP_User( $user ); $staff_caps = dokan_get_staff_capabilities(); $staff->add_cap( 'dokandar' ); $staff->add_cap( 'delete_pages' ); $staff->add_cap( 'publish_posts' ); $staff->add_cap( 'edit_posts' ); $staff->add_cap( 'delete_published_posts' ); $staff->add_cap( 'edit_published_posts' ); $staff->add_cap( 'delete_posts' ); $staff->add_cap( 'manage_categories' ); $staff->add_cap( 'moderate_comments' ); $staff->add_cap( 'upload_files' ); $staff->add_cap( 'edit_shop_orders' ); $staff->add_cap( 'edit_product' ); foreach ( $staff_caps as $key => $staff_cap ) { $staff->add_cap( $staff_cap ); } update_user_meta( $user, 'dokan_enable_selling', 'yes' ); update_user_meta( $user, '_vendor_id', sanitize_text_field( $post_data['vendor_id'] ) ); update_user_meta( $user, '_staff_phone', sanitize_text_field( $post_data['phone'] ) );
One piece of metadata that can be updated through the handle_staff()
function is the ‘_vendor_id’ value which controls what vendor a particular staff member is assigned to. This means that this value could be updated arbitrarily from any vendor’s account making it possible to assign any vendor ID to any staff account.
Further examination of the code reveals that the plugin uses the dokan_get_current_user_id()
function to determine and return the current user ID.
function dokan_get_current_user_id() { if ( current_user_can( 'vendor_staff' ) ) { $staff_id = get_current_user_id(); $vendor_id = (int) get_user_meta( $staff_id, '_vendor_id', true ); if ( empty( $vendor_id ) ) { return $staff_id; } return $vendor_id; } return get_current_user_id(); }
This function returns the vendor ID, which we previously established to be a user controlled value, as the current user ID in the case of staff users.
This ultimately makes it possible for authenticated attackers, with vendor-level permission, to add a staff user and assign the administrator as the vendor to it via the ‘_vendor_id’ meta value. Then, once logged in as the staff user, they can change the administrator’s password via a profile update due to the special dokan_get_current_user_id()
function.
As with any Arbitrary User Password Change that leads to a Privilege Escalation vulnerability, this can be used for complete site compromise. Once an attacker has gained administrative user access to a WordPress site, they can then manipulate anything on the targeted site as a normal administrator would. This includes the ability to upload plugin and theme files, which can be malicious zip files containing backdoors, and to modify posts and pages which can be leveraged to redirect site users to other malicious sites or inject spam content.
Disclosure Timeline
June 5, 2025 – We received the submission for the Privilege Escalation vulnerability in Dokan Pro via the Wordfence Bug Bounty Program.
June 9, 2025 – We validated the report and confirmed the proof-of-concept exploit.
June 9, 2025 – We initiated outreach to the vendor, letting them know we had a new vulnerability to disclose and offering them access to the Wordfence Vulnerability Management Portal to manage the disclosure.
June 10, 2025 – Wordfence Premium, Care, and Response users received a firewall rule to provide protection against any exploits that may target this vulnerability.
June 12, 2025 – The vendor registered on our Wordfence Vulnerability Management Portal for WordPress vendors.
June 17, 2025 – The full disclosure details were sent instantly to the vendor upon verifying ownership of their software. The vendor acknowledged the report and began working on a fix.
July 10, 2025 – Wordfence Free users received the same protection.
August 6, 2025 – The fully patched version of the plugin, 4.0.6, was released.
Conclusion
In this blog post, we detailed a Privilege Escalation vulnerability within the Dokan Pro plugin affecting versions 4.0.5 and earlier. This vulnerability makes it possible for authenticated threat actors with vendor-level permission to easily take over websites by resetting the password of any user, including administrators. The vulnerability has been fully addressed in version 4.0.6 of the plugin.
We encourage WordPress users to verify that their sites are updated to the latest patched version of Dokan Pro as soon as possible considering the critical nature of this vulnerability.
Wordfence Premium, Wordfence Care, and Wordfence Response users received a firewall rule to protect against any exploits targeting this vulnerability on June 10, 2025. Sites using the free version of Wordfence received the same protection 30 days later on July 10, 2025.
If you know someone who uses this plugin on their site, we recommend sharing this advisory with them to ensure their site remains secure, as this vulnerability poses a significant risk.
The post 15,000 WordPress Sites Affected by Privilege Escalation Vulnerability in Dokan Pro WordPress Plugin appeared first on Wordfence.