diff --git a/js/qsm-admin.js b/js/qsm-admin.js index e5d913bfe..d71bcb7e1 100644 --- a/js/qsm-admin.js +++ b/js/qsm-admin.js @@ -3763,6 +3763,7 @@ var import_button; tinymce: { plugins: ["qsmslashcommands"], forced_root_block: '', + encoding: 'xml', toolbar1: 'formatselect,bold,italic,underline,bullist,numlist,blockquote,alignleft,aligncenter,alignright,link,wp_more,fullscreen,wp_adv', toolbar2: 'strikethrough,hr,forecolor,pastetext,removeformat,charmap,outdent,indent,undo,redo,wp_help,wp_code' }, diff --git a/php/classes/class-qsm-results-pages.php b/php/classes/class-qsm-results-pages.php index f9dea5819..63c72fd99 100644 --- a/php/classes/class-qsm-results-pages.php +++ b/php/classes/class-qsm-results-pages.php @@ -177,7 +177,8 @@ public static function generate_pages( $response_data ) { // Decodes special characters, runs through our template // variables, and then outputs the text. - $page = htmlspecialchars_decode( $content, ENT_QUOTES ); + //$page = htmlspecialchars_decode( $content, ENT_QUOTES ); + $page = wp_kses_post( $content ); //last chance to filter $page $page = apply_filters( 'qsm_template_variable_results_page', $page, $response_data ); @@ -320,6 +321,42 @@ public static function convert_to_new_system( $quiz_id ) { return $pages; } + public static function sanitize_html( $html = '' ) { + + // Remove unwanted html tags + $html = preg_replace('/<(script|form|textarea|div|body|title|svg|link|meta)[^>]*>.*?<\/\1>/is', '', $html); + + // Remove input tags + $html = preg_replace('/]*>/i', '', $html); + + // Remove any on event attributes + $html = preg_replace('/\s*on\w+\s*=\s*("[^"]*"|\'[^\']*\'|[^\s>]+)/i', '', $html); + + // Remove any alert, confirm, or prompt calls + $html = preg_replace('/\b(alert|confirm|prompt)\s*\(\s*[^;]*\s*\)\s*;?/i', '', $html); + + // Remove any javascript: URLs + $html = preg_replace('/javascript:/i', '', $html); + + // Filter image src for possible image types, safe URL, and no $_GET parameters + $html = preg_replace_callback('/]*>/i', function($matches) { + $src = $matches[1]; + $valid_image_types = array('jpg', 'jpeg', 'png', 'gif', 'webp' ); + $file_extension = pathinfo($src, PATHINFO_EXTENSION); + $url_parts = parse_url($src); + + if (in_array(strtolower($file_extension), $valid_image_types) && + isset($url_parts['scheme']) && in_array(strtolower($url_parts['scheme']), array('http', 'https')) && + empty($url_parts['query'])) { + return ''; + } else { + return ''; + } + }, $html); + + return $html; + } + /** * Saves the results pages for a quiz. * @@ -367,8 +404,13 @@ public static function save_pages( $quiz_id, $pages ) { // Sanitize template data if ( isset( $pages[ $i ]['page'] ) && $is_not_allow_html ) { - $pages[ $i ]['page'] = wp_kses_post( preg_replace( '/([^<]+)<\/span>/', '%$1%', $pages[ $i ]['page'] ) ); - + $pages[ $i ]['page'] = QSM_Results_Pages::sanitize_html( $pages[ $i ]['page'] ); + //Check if encoded html string given + if ( false === stripos( $pages[ $i ]['page'] ,'<span class="qsm-highlight-variables">') ) { + $pages[ $i ]['page'] = wp_kses_post( preg_replace( '/([^<]+)<\/span>/', '%$1%', $pages[ $i ]['page'] ) ); + } else { + $pages[ $i ]['page'] = wp_kses_post( preg_replace('/<span class="qsm-highlight-variables">([^&]+)<\/span>/i', '%$1%', $pages[ $i ]['page'] ) ); + } } $pages[ $i ]['default_mark'] = sanitize_text_field( $pages[ $i ]['default_mark'] ); diff --git a/php/rest-api.php b/php/rest-api.php index 509d0f2cc..935ac4703 100644 --- a/php/rest-api.php +++ b/php/rest-api.php @@ -40,7 +40,9 @@ function qsm_register_rest_routes() { array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => 'qsm_rest_save_question', - 'permission_callback' => '__return_true', + 'permission_callback' => function () { + return current_user_can( 'edit_posts' ); + }, ) ); register_rest_route( @@ -67,7 +69,9 @@ function qsm_register_rest_routes() { array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => 'qsm_rest_save_results', - 'permission_callback' => '__return_true', + 'permission_callback' => function () { + return current_user_can( 'edit_posts' ); + }, ) ); register_rest_route(