Plugin Directory

Changeset 3433666


Ignore:
Timestamp:
01/06/2026 01:49:46 PM (3 months ago)
Author:
expresstech
Message:

10.3.4 to trunk

Location:
quiz-master-next/trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • quiz-master-next/trunk/css/admin-dashboard.css

    r3357783 r3433666  
    144144    background: #0f0fea;
    145145}
    146 
     146.changelog-ul li .patch {
     147    background: #d5fdff;
     148    color: #1e616a;
     149}
     150.changelog-ul li .patch::before {
     151    background: #1e616a;
     152}
    147153.changelog-ul li span.bug:before, .changelog-ul li span.hotfix:before, .changelog-ul li span.fix:before{
    148154    background: #9D174D;
  • quiz-master-next/trunk/mlw_quizmaster2.php

    r3423678 r3433666  
    33 * Plugin Name: Quiz And Survey Master
    44 * Description: Easily and quickly add quizzes and surveys to your website.
    5  * Version: 10.3.3
     5 * Version: 10.3.4
    66 * Author: ExpressTech
    77 * Author URI: https://quizandsurveymaster.com/
     
    4444     * @since 4.0.0
    4545     */
    46     public $version = '10.3.3';
     46    public $version = '10.3.4';
    4747
    4848    /**
  • quiz-master-next/trunk/php/admin/options-page-questions-tab.php

    r3410860 r3433666  
    935935    }
    936936    $question_id = isset( $_POST['question_id'] ) ? intval( $_POST['question_id'] ) : 0;
     937    if ( $question_id && ! qsm_user_can_modify_question_ids( array( $question_id ) ) ) {
     938        wp_send_json_error(
     939            array(
     940                'message' => __( 'You are not allowed to modify this question.', 'quiz-master-next' ),
     941            )
     942        );
     943    }
    937944    if ( $question_id > 0 ) {
    938945        qsm_process_unlink_question_from_list_by_question_id( $question_id );
     
    951958}
    952959add_action( 'wp_ajax_qsm_unlink_question_from_list', 'qsm_ajax_unlink_question_from_list' );
     960
     961/**
     962 * Checks whether current user can modify given question IDs based on quiz ownership.
     963 *
     964 * @param array $question_ids Question IDs.
     965 *
     966 * @return bool
     967 */
     968function qsm_user_can_modify_question_ids( $question_ids ) {
     969    global $wpdb;
     970
     971    $question_ids = array_filter( array_map( 'intval', (array) $question_ids ) );
     972    if ( empty( $question_ids ) ) {
     973        return false;
     974    }
     975
     976    $placeholders = implode( ', ', array_fill( 0, count( $question_ids ), '%d' ) );
     977    $quiz_ids     = $wpdb->get_col(
     978        $wpdb->prepare(
     979            "SELECT DISTINCT quiz_id FROM {$wpdb->prefix}mlw_questions WHERE question_id IN ( $placeholders )",
     980            $question_ids
     981        )
     982    );
     983
     984    $current_user = get_current_user_id();
     985    foreach ( $quiz_ids as $quiz_id ) {
     986        $post_id = $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = 'quiz_id' AND meta_value = %d LIMIT 1", intval( $quiz_id ) ) );
     987        // If quiz mapping is missing, only allow elevated users.
     988        if ( empty( $post_id ) && ! current_user_can( 'edit_others_qsm_quizzes' ) ) {
     989            return false;
     990        }
     991
     992        if ( ! empty( $post_id ) ) {
     993            $post_author = intval( get_post_field( 'post_author', $post_id, true ) );
     994            $owns_quiz   = ( $post_author === $current_user );
     995
     996            if ( ( ! current_user_can( 'edit_qsm_quiz', $post_id ) || ! $owns_quiz ) && ! current_user_can( 'edit_others_qsm_quizzes' ) ) {
     997                return false;
     998            }
     999        }
     1000    }
     1001
     1002    return true;
     1003}
    9531004
    9541005/**
     
    10051056
    10061057    global $mlwQuizMasterNext;
     1058    global $wpdb;
    10071059    $json    = array(
    10081060        'status' => 'error',
    10091061    );
    10101062    $quiz_id = isset( $_POST['quiz_id'] ) ? intval( $_POST['quiz_id'] ) : 0;
    1011     $post_id = isset( $_POST['post_id'] ) ? intval( $_POST['post_id'] ) : 0;
     1063
     1064    // Map quiz to its post and enforce edit capabilities.
     1065    $post_id    = $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = 'quiz_id' AND meta_value = %d LIMIT 1", $quiz_id ) );
     1066    $post_author = get_post_field( 'post_author', $post_id, true );
     1067
     1068    if ( empty( $post_id ) || ( ( ! current_user_can( 'edit_qsm_quiz', $post_id ) || intval( $post_author ) !== get_current_user_id() ) && ! current_user_can( 'edit_others_qsm_quizzes' ) ) ) {
     1069        wp_die( esc_html__( 'You are not allowed to edit this quiz, You need higher permission!', 'quiz-master-next' ) );
     1070    }
     1071
    10121072    $mlwQuizMasterNext->pluginHelper->prepare_quiz( $quiz_id );
    10131073    $pages         = isset( $_POST['pages'] ) ? qsm_sanitize_rec_array( wp_unslash( $_POST['pages'] ) ) : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
     
    11711231    $question_ids = isset( $_POST['question_ids'] ) ? sanitize_text_field( wp_unslash( $_POST['question_ids'] ) ) : '';
    11721232    $question_arr = explode( ',', $question_ids );
     1233    if ( $question_arr && ! qsm_user_can_modify_question_ids( $question_arr ) ) {
     1234        echo wp_json_encode(
     1235            array(
     1236                'success' => false,
     1237                'message' => __(
     1238                    'You are not allowed to modify these questions.',
     1239                    'quiz-master-next'
     1240                ),
     1241            )
     1242        );
     1243        wp_die();
     1244    }
    11731245    $response     = array();
    11741246    if ( $question_arr ) {
     
    12101282    }
    12111283    $base_question_id = $question_id = isset( $_POST['question_id'] ) ? intval( $_POST['question_id'] ) : 0;
     1284    if ( $question_id && ! qsm_user_can_modify_question_ids( array( $question_id ) ) ) {
     1285        wp_send_json_error( __( 'You are not allowed to modify this question.', 'quiz-master-next' ) );
     1286    }
    12121287    if ( $question_id ) {
    12131288
     
    12871362
    12881363    if ( ! empty( $question_id ) ) {
     1364        if ( ! qsm_user_can_modify_question_ids( $question_id ) ) {
     1365            wp_send_json_error( __( 'You are not allowed to modify these questions.', 'quiz-master-next' ) );
     1366        }
    12891367
    12901368        $update_qpages_after_delete = array();
  • quiz-master-next/trunk/php/classes/class-qsm-results-pages.php

    r3341668 r3433666  
    363363                $pages[ $i ]['redirect'] = false;
    364364            } else {
    365                 $pages[ $i ]['redirect'] = esc_url( $pages[ $i ]['redirect'] );
     365                $pages[ $i ]['redirect'] = false !== strpos( $pages[ $i ]['redirect'], '%RESULT_LINK%' ) ? $pages[ $i ]['redirect'] : esc_url( $pages[ $i ]['redirect'] );
    366366            }
    367367
  • quiz-master-next/trunk/readme.txt

    r3430156 r3433666  
    55Tested up to: 6.9
    66Requires PHP: 5.4
    7 Stable tag: 10.3.3
     7Stable tag: 10.3.4
    88License: GPLv2
    99License URI: http://www.gnu.org/licenses/gpl-2.0.html
     
    226226
    227227== Changelog ==
     228= 10.3.4 ( January 06, 2026 ) =
     229* Patch: Vulnerability where users can modify or delete quizzes/questions beyond their role permissions
     230* Enhancement: Added support for using variable in quiz redirect URL
     231
     232
    228233= 10.3.3 ( December 19, 2025 ) =
    229 * Fix: Broken Access Control vulnerability
     234* Patch: Broken Access Control vulnerability
    230235
    231236= 10.3.2 ( December 04, 2025 ) =
Note: See TracChangeset for help on using the changeset viewer.