Changeset 3362561
- Timestamp:
- 09/16/2025 12:55:38 PM (7 months ago)
- Location:
- chained-quiz/trunk
- Files:
-
- 5 edited
-
chained-quiz.php (modified) (1 diff)
-
controllers/quizzes.php (modified) (3 diffs)
-
controllers/social-sharing.php (modified) (2 diffs)
-
helpers/htmlhelper.php (modified) (1 diff)
-
models/quiz.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
chained-quiz/trunk/chained-quiz.php
r3219454 r3362561 5 5 Description: Create a chained quiz where the upcoming questions can depend on the previous answer 6 6 Author: Kiboko Labs 7 Version: 1.3. 37 Version: 1.3.4 8 8 Author URI: http://calendarscripts.info/ 9 9 License: GPLv2 or later -
chained-quiz/trunk/controllers/quizzes.php
r2826623 r3362561 184 184 185 185 // store the answer 186 if(!empty($_COOKIE['chained_completion_id'.$quiz->id])) { 186 if(!empty($_COOKIE['chained_completion_id'.$quiz->id])) { 187 $completion_id = intval($_COOKIE['chained_completion_id'.$quiz->id]); 188 189 // Validate completion ownership to prevent IDOR 190 if (!chained_validate_completion_ownership($completion_id, $quiz->id)) { 191 die(__('Unauthorized access to quiz completion.', 'chained')); 192 } 193 187 194 if(is_array($answer)) { 188 195 $answer = chained_int_array($answer); … … 195 202 $exists = $wpdb->get_var($wpdb->prepare("SELECT id FROM ".CHAINED_USER_ANSWERS." 196 203 WHERE quiz_id=%d AND completion_id=%d AND question_id=%d", 197 $quiz->id, intval($_COOKIE['chained_completion_id'.$quiz->id]), $question->id));204 $quiz->id, $completion_id, $question->id)); 198 205 199 206 $choice_choice = $choice_correct = ''; … … 215 222 answer=%s, points=%f, comments=%s, is_correct=%d 216 223 WHERE quiz_id=%d AND completion_id=%d AND question_id=%d", 217 $answer, $points, $comments, $correct_var, $quiz->id, intval($_COOKIE['chained_completion_id'.$quiz->id]), $question->id));224 $answer, $points, $comments, $correct_var, $quiz->id, $completion_id, $question->id)); 218 225 } 219 226 else { 220 227 $wpdb->query($wpdb->prepare("INSERT INTO ".CHAINED_USER_ANSWERS." SET 221 228 quiz_id=%d, completion_id=%d, question_id=%d, answer=%s, points=%f, comments=%s, is_correct=%d", 222 $quiz->id, intval($_COOKIE['chained_completion_id'.$quiz->id]), $question->id, $answer, $points, $comments, $correct_var));229 $quiz->id, $completion_id, $question->id, $answer, $points, $comments, $correct_var)); 223 230 } 224 231 225 232 // update the "completed" record as non empty 226 $wpdb->query($wpdb->prepare("UPDATE ".CHAINED_COMPLETED." SET not_empty=1 WHERE id=%d", intval($_COOKIE['chained_completion_id'.$quiz->id])));233 $wpdb->query($wpdb->prepare("UPDATE ".CHAINED_COMPLETED." SET not_empty=1 WHERE id=%d", $completion_id)); 227 234 } 228 235 -
chained-quiz/trunk/controllers/social-sharing.php
r2825114 r3362561 33 33 global $wpdb; 34 34 $taking_id = intval($GLOBALS['chained_completion_id']); 35 36 // Get the quiz_id from the completion record 37 $completion = $wpdb->get_row($wpdb->prepare("SELECT * FROM " . CHAINED_COMPLETED . " WHERE id = %d", $taking_id)); 38 39 // Validate completion ownership to prevent IDOR 40 if ($taking_id && $completion && !chained_validate_completion_ownership($taking_id, $completion->quiz_id)) { 41 die(__('Unauthorized access to quiz completion.', 'chained')); 42 } 35 43 36 44 ob_start(); … … 142 150 if(empty($_GET['tid']) or empty($_GET['chained_sssnippet'])) return false; 143 151 $taking_id = intval($_GET['tid']); 152 153 // Validate completion ownership to prevent IDOR 154 $completion = $wpdb->get_row($wpdb->prepare("SELECT * FROM " . CHAINED_COMPLETED . " WHERE id = %d", $taking_id)); 155 if ($taking_id && $completion && !chained_validate_completion_ownership($taking_id, $completion->quiz_id)) { 156 wp_die(__('Unauthorized access to quiz completion.', 'chained')); 157 return; 158 } 144 159 145 160 // select taking -
chained-quiz/trunk/helpers/htmlhelper.php
r3045828 r3362561 113 113 return $_SERVER['REMOTE_ADDR']; 114 114 } 115 116 // Validate if a completion ID belongs to the current user/session 117 function chained_validate_completion_ownership($completion_id, $quiz_id) { 118 global $wpdb, $user_ID; 119 120 // Get the completion record 121 $completion = $wpdb->get_row($wpdb->prepare( 122 "SELECT * FROM " . CHAINED_COMPLETED . " WHERE id = %d AND quiz_id = %d", 123 $completion_id, 124 $quiz_id 125 )); 126 127 // If completion record doesn't exist, return false 128 if (!$completion) { 129 return false; 130 } 131 132 // If user is logged in, check if the completion belongs to them 133 if (is_user_logged_in()) { 134 return ($completion->user_id == $user_ID); 135 } else { 136 // For non-logged in users, check IP address 137 // Note: This is not 100% secure as IPs can be shared, but it's better than nothing 138 $ip = chained_user_ip(); 139 return ($completion->ip == $ip); 140 } 141 142 return false; 143 } -
chained-quiz/trunk/models/quiz.php
r3107260 r3362561 100 100 $completion_id = empty($_COOKIE['chained_completion_id'.$quiz->id]) ? 0 : intval($_COOKIE['chained_completion_id'.$quiz->id]); 101 101 102 // Validate completion ownership to prevent IDOR 103 if ($completion_id && !chained_validate_completion_ownership($completion_id, $quiz->id)) { 104 die(__('Unauthorized access to quiz completion.', 'chained')); 105 } 106 102 107 $_result = new ChainedQuizResult(); 103 108 // calculate result … … 171 176 172 177 // now insert in completed 173 if(!empty($_COOKIE['chained_completion_id'.$quiz->id])) { 178 if(!empty($_COOKIE['chained_completion_id'.$quiz->id])) { 174 179 $wpdb->query( $wpdb->prepare("UPDATE ".CHAINED_COMPLETED." SET 175 180 quiz_id = %d, points = %f, result_id = %d, datetime = NOW(), ip = %s, user_id = %d, 176 181 snapshot = %s, source_url=%s, email=%s WHERE id=%d", 177 182 $quiz->id, $points, @$result->id, chained_user_ip(), $user_id, $output, 178 $source_url, $user_email, intval($_COOKIE['chained_completion_id'.$quiz->id])));183 $source_url, $user_email, $completion_id)); 179 184 180 185 $taking_id = $_COOKIE['chained_completion_id'.$quiz->id];
Note: See TracChangeset
for help on using the changeset viewer.