Critical Unauthenticated SQL Injection in Quiz And Survey Master <= 8.1.4

Published 18 April 2023
Updated 24 July 2023
Rafie Muhammad
Security Researcher at Patchstack
Table of Contents

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.

Patchstack paid plan users are protected from the vulnerability. You can also sign up for the Patchstack Community plan to be notified about vulnerabilities as soon as they become disclosed.

For plugin developers, we have security audit services and Threat Intelligence Feed API for hosting companies.

About 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.

Quiz And Survey Master

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:

Quiz And Survey Master

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:

Quiz And Survey Master


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.

Help us make the Internet a safer place

Making the WordPress ecosystem more secure is a team effort, and we believe that plugin developers and security researchers should work together.

  • If you're a plugin developer, join our mVDP program that makes it easier to report, manage and address vulnerabilities in your software.
  • If you're a security researcher, join Patchstack Alliance to report vulnerabilities & earn rewards.

The latest in Security Advisories

Looks like your browser is blocking our support chat widget. Turn off adblockers and reload the page.