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 hostsAbout Quiz and Survey Master plugin
The 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.

PHP Object Injection
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
.
The patch
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.


Conclusion
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.
Want to learn more about finding and fixing vulnerabilities?
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.
Timeline
🤝 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