This blog post is about the Quiz And Survey Master plugin vulnerability. If you're a Quiz And Survey Master user, please update the plugin to at least version 8.1.5.
✌️ Our users are protected from this vulnerability. Are yours?
Automatically mitigate vulnerabilities in real-time without changing code.
See pricingIdentify vulnerabilities in your plugins and get recommendations for fixes.
Request auditProtect your users, improve server health and earn additional revenue.
Patchstack for hostsAbout the Quiz And Survey Master WordPress plugin
The plugin Quiz And Survey Master (versions 8.1.4 and below, free version), which has over 40,000 active installations are known as one of the more popular quiz and survey plugins in WordPress.

This plugin is claimed to be the easiest WordPress Quiz Plugin that can be used to create engaging content to drive traffic and increase user engagement. Everything from the viral quiz, trivia quiz, and customer satisfaction surveys to employee surveys.
The security vulnerability in Quiz And Survey Master plugin
This plugin suffers from an unauthenticated SQL injection vulnerability. This vulnerability allows any unauthenticated user to perform SQL injection. The described vulnerability was fixed in version 8.1.5 and assigned CVE-2023-28787.
Find out more from the Patchstack database.
The security vulnerability in Quiz And Survey Master was first discovered in version 8.1.2. The vulnerable code exists in the load_questions
function that handles the process of displaying a list of questions in the plugin.
---------------------------
if ( 1 == $quiz_options->randomness_order || 2 == $quiz_options->randomness_order ) {
if ( isset($_COOKIE[ 'question_ids_'.$quiz_id ]) ) {
$question_sql = sanitize_text_field( wp_unslash( $_COOKIE[ 'question_ids_'.$quiz_id ] ) );
}else {
$question_ids = apply_filters( 'qsm_load_questions_ids', $question_ids, $quiz_id, $quiz_options );
$question_ids = QMNPluginHelper::qsm_shuffle_assoc( $question_ids );
$question_sql = implode( ',', $question_ids );
---------------------------
}
$order_by_sql = 'ORDER BY FIELD(question_id,'.$question_sql.')';
}
$query = $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}mlw_questions WHERE question_id IN (%1s) %2s %3s %4s", $question_sql, $cat_query, $order_by_sql, $limit_sql );
$questions = $wpdb->get_results( stripslashes( $query ) );
---------------------------
The code will first check if the quiz settings enabled the randomness option and will construct $question_sql
directly from $_COOKIE[ 'question_ids_'.$quiz_id]
if it's provided. The $question_sql
variable then will be directly concatenated to the $order_by_sql
variable.
The $question_sql
and $order_by_sql
variables then will be supplied to the $query
variable using $wpdb->prepare
as the first parameter and third parameter. Since the SQL Injection payload resides in $question_sql
and $order_by_sql
is not formatted inside of quotes, it is possible to construct a quote-less payload to trigger the SQL Injection.
The patch in Quiz And Survey Master
The plugin vendor tried to publish a patch in version 8.1.3 with this code changes:

The above patch is still not sufficient to prevent SQL Injection. This is because the esc_sql()
function only escape strings that are placed inside of quotes. In this case, we are still able to inject a quote-less SQL Injection payload to the $question_sql
and $order_by_sql
variables.
Since the intended process of the code is to process a sequence number of questions id like 1,2,3,4,5, we recommend a patch code that will check the input from $_COOKIE[ 'question_ids_'.$quiz_id]
using a simple regex. The plugin vendor finally fully patched the vulnerability in version 8.1.5 with the following code changes:

Conclusion
Always secure the SQL process in plugins or themes with proper function and implementation. Both are important since the usage of proper functions to prevent SQL Injection like esc_sql() and $wpdb->prepare alone are not enough to prevent SQL Injection if the usage implementation is not proper.
Keep in mind to give more attention to the SQL query construction where implementation is not wrapped by quotes like IN
, GROUP BY
, ORDER BY
, etc.
Disclosure timeline of the vulnerability
24-03-2023 - We found the vulnerability and reached out to the plugin vendor.
29-03-2023 - Quiz And Survey Master plugin version 8.1.3 was published with an incomplete patch.
13-04-2023 - Quiz And Survey Master plugin version 8.1.5 was published to fully patch the reported issues.
16-04-2023 - Added the vulnerabilities to the Patchstack vulnerability database.
18-04-2023 - Published the article.
🤝 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 more