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(