Advisory:

CSRF/stored XSS in Quiz And Survey Master (Formerly Quiz Master Next) allows unauthenticated attackers to do almost anything an admin can

Vulnerability

Last revised: December 7, 2016

A CSRF vulnerability allows an unauthenticated attacker to add questions to existing quizzes.

The question_name parameter is put into a manually-constructed JavaScript object and escaped with esc_js() (php/qmn_options_questions_tab.php line 499). If the user (or attacker) creates a new question on a quiz containing “<script>alert(1)</script>” in the question_name field then “question: ‘&lt;script&gt;alert(1)&lt;/script&gt;’,” will get output inside the JS object. All good so far.

However, in js/admin_question.js on line 205, we see this line, as part of some JS-generated HTML:

This looks okay. We’re creating a TEXTAREA element, setting its HTML to the value of the question_name parameter, and extracting the .text() of it. If we did jQuery(‘<textarea/>’).html(‘<script>alert(1)</script>’).text() we would get “alert(1)” as the output.

However, that’s not how inline JavaScript gets parsed. Between a <script> and a </script>, the HTML parser actually parses “&lt;” as “&lt;” not as “<“. So if we do jQuery(‘<textarea/>’).html(‘&lt;script&gt;alert(1)&lt;/script&gt;’).text() we get “<script>alert(1)</script>”.

And since “<script>alert(1)</script>” doesn’t appear anywhere in the page, Chrome’s reflected XSS mitigation measures are not activated. Thus the stored XSS attack can be executed immediately.