Hi,

For a project I'm working on for the Radboud University in Nijmegen we need to integrate javascript into ClosedQuestion questions. Currently this isn't possible as the XML-parser used by ClosedQuestion doesn't allow <script /> tags.

To solve this we could simply add the <script /> tag to the list of allowed tags. However we don't think that this is a neat solution. Therefore we propose to separate content from structure by using CDATA sections in the XML-structure so HTML content isn't part of the XML-tree but is data in the XML tree. Allowing or disallowing certain HTML-tags will be handled by the default input-filters afterwards.

We'll do this by building an new XML-parser but with keeping the old one intact so the new version will be backwards compatible.

What do you think of this separation? Any comments on it?

CommentFileSizeAuthor
#8 1673444v1.patch6.83 KBtimcooijmans

Comments

jvdkolk’s picture

Hi Tim!

For the record: If made, it would be great if this could also be implemented int the 7.x branch (which should be not too difficult).

Koos

HylkeVDS’s picture

Wrapping HTML into CDATA tags is a bad idea since in many cases there are tags in the HTML that need to be parsed (like feedback blocks and inline options).

Putting javascipt into questions is a potential security risk and thus should never be allowed by default.

What functionality do you need that requires javascript in your questions? It's probably better to make that functionality part of CQ so the questions don't need embedded js.

timcooijmans’s picture

I'm aware of the fact that there are non-HTML tags in the HTML section that need to be parsed. These tags within CDATA sections will be parsed.

Allowing javascript by default is a potential security risk indeed. But it should be handled on the level of input filters not on the level of Closed Question. The HTML filter which is provided in Drupal by default is there for that reason.

We'll use various javascript applets that will communicate state (selected option for example) to an hidden field which will act as a kind of fill-in question.

jvdkolk’s picture

You could think of incorporating JavaScript-driven 'widgets' into questions, e.g. interactive charts: http://people.iola.dk/olau/flot/examples/interacting.html.

Of course you could make an 'interactive chart' question type, but wouldnt it be nice to have a more flexible approach?

(BTW: What exactly is the security risk, if the site admin/teacher is the only one able to add JavaScript to the questions?)

HylkeVDS’s picture

CDATA sections are not parsed. If you do parse CDATA sections separately it doesn't solve the problem, since that just means the second parser needs to know the tags any way. Then you might as well let the first parser do it and add the script tag to the list of known tags. Wrapping the html in a CDATA block is meaningless.

Teachers and administrators are busy people, so they tend to delegate question editing to student assistants. I can totally imagine a student assistant trying to get site-root-rights by planting javascript in a question that changes his account status the first time an admin visits the question.

timcooijmans’s picture

I'm fully aware of the fact that CDATA sections are not parsed at the moment. A CDATA parser should only parse the Closed Question related tags (like the inline options) and leave deciding which HTML-tags to allow to the HTML filter.

The beautiful part of my solution is that you can define different input formats with different input filters for different groups of users. In our case we'll have an administrator who will do most of the work so we'll give him full rights. If a student assistant has to do some work, than you can define an other input filter that doesn't allow the usage of <script /> tags.

timcooijmans’s picture

Issue summary: View changes

Added something about backwards compatibility

HylkeVDS’s picture

You can already do that. All the html is run through the input filters. All you need to do is change the current parser to not strip unknown tags as the default. No need for a second parser at all. You could make that setting configurable. Changing that default should generate a nice big warning that it's an unsafe setting.

timcooijmans’s picture

StatusFileSize
new6.83 KB

I created a first proposal: This change allows the disabling of the XML-filtering by a setting. The patch is based on the 6.x-2.x branch and I haven't tested it on 7.x.

Any comments are welcome.

timcooijmans’s picture

Assigned: timcooijmans » Unassigned
jvdkolk’s picture

@Hylke: what if we force Javascript to be run in a sandbox? E.g. https://github.com/eligrey/jsandbox. Javascript running inside this library cannot reach the webpage/place cookies/etc, but only objects we specify.

Allowing power users to add some scripts could make CQ even more versatile.

timcooijmans’s picture

In our past project we simply needed full JavaScript to enable our questions. That's why we created the option. We use input formats to allow or disallow certain people to enter JavaScript or other malicious content.

The default page in Drupal also allows all JavaScript when the right input format is selected. My modifications don't allow JavaScript the be executed by default. You first have to enable full XML parsing in the newly made ClosedQuestion settings and you have to create an input format that allows JavaScript.

jvdkolk’s picture

@tim I have been thinking about your request driving back to Wageningen. There is one thing that I do not understand: why did you not create separate CQ-question types for the questions you need for your client?

The way I see it, there are a couple of 'question archetypes', e.g. fill blanks. Build on these archetypes one can make many (Javascript generated) user interfaces, e.g. an interactive graph in which students have to click somewhere. When a students makes such a click, Javascript fills out the -hidden- fill blank's for him/her e.g. based on the coordinates.

In the CQ-XML definition there could be then something like:

<subtype name="graph"> interactive graph settings here, which will be passed on to Javascript </subtype>

so CQ knows what Javascript to load with what parameters. Did you consider this option?

timcooijmans’s picture

We did, but we didn't consider it fit for several reasons:

  1. The questions we make are quite unique, we have like 10 different designs at the moment. Also the questions we use do not contain only a java applet but also some textual content or even images.
  2. We wanted to treat the ClosedQuestion page just like any other page with the same possibilities.
  3. We wanted to provide the people who create questions with the flexibility to use their own JavaScript applets. However these people may not have access to the actual ClosedQuestion source.
  4. We don't want to pollute the ClosedQuestion module with whatever question type we think we need. We think that the ClosedQuestion module should provide a solid basis on which more complicated questions can be build.
  5. We had to develop the Molecule module which provides the input filter we use anyway because we also use it in normal page nodes. So we added an option to it to sync it with ClosedQuestion questions.
jvdkolk’s picture

Ad 2. This would still be the case with the question 'subtypes', I think.

Ad 3. Personally I agree to this, so my idea can also be considered as an addition to your proposal. The disadvantage of the JS-option is that non-technical teachers out there cannot profit from the question-types you created.

Ad 1+4. I believe the more use cases covered, the better :) As long as things are being documented, of course.

timcooijmans’s picture

The questions we created are not that difficult for teachers to make. This is an example question (the answer mapping section is removed) even without JavaScript in the body we couldn't make without our changes to the ClosedQuestion parser.

<question type="fillblanks"> 
<text>
<p>Look at the spectrum and structure of 1-hexyne below. Which peak corresponds to the stretch vibration of the indicated bond? Click on the correct peak and then submit.</p>
<spectrum closedquestionsync="PeakID1"  width="450" height="350" file=""/><img src="" /> 
<p style="display:none"><inlineChoice identifier="PeakID1" freeform="1"/></p>
</text>
</question>

We can't run this question through the normal XML filter because the <spectrum /> tag will be filtered out.

This same <spectrum /> tag is also used in content on pages. So in that way we want ClosedQuestion to behave like a normal page.

If you wanted to include these type of questions in ClosedQuestion you would have to include JavaScript specific to our Molecule module. If you wanted the questions to actually work (without downloading extra files) you would even have to include the Java applets themselves. We have plans to embed several more Java or Javascript applets. I don't think that it's a good idea to include all these applets and their code into the ClosedQuestion project.

jvdkolk’s picture

Another question: what are the risks of badly-written custom JavaScript? So in this scenario the student assistant writing the custom CQ is not evil, but ignorant of the security risks of Javascript. He/she produces JavaScript code which is, e.g., vulnerable for XSS attacks, as the code deals with end-user generated data. What is the worst thing that can happen in this scenario?

I don't think that it's a good idea to include all these applets and their code into the ClosedQuestion project.

Maybe not, but ClosedQuestion could check for the existence of the modules bringing these third-party libraries to Drupal (e.g. http://drupal.org/project/molecule) and then offer the possibility to create questions with them. In that way, the modularity of CQ is preserved.

timcooijmans’s picture

Our Molecule module works in CQ even if you would disable inline JavaScript. We provide the JavaScript needed in the Molecule module and load this file. However we do provide custom XML tags that have to be included in HTML (for example the <spectrum /> tag in the previous example). The "old" XML parser that CQ uses, has a fixed set of XML tags that are allowed. Of course the <spectrum /> tag isn't allowed so it doesn't work.

So we modified the CQ XML parser to use the input filters provided in Drupal. For example we could create a input filter that only allows our Molecule tags and doesn't allow JavaScript to enable student assistants to create questions but mitigate the attack possibilities by disabling JavaScript tags.

To answer your question: I can't come-up with an realistic attack that would use badly written JavaScript. But I'm not saying that it isn't possible because I could write an attack for this. First of all, JavaScript runs in the browser so any attacker can swap out the existing code with his own in his own browser. You normally don't trust data coming from the client either by normal HTTP requests or requests initiated by JavaScript. The only problem thus left is badly written JavaScript that allows XSS in the CQ results page. This is something that, if present, is also exploitable without bad JavaScript so I don't see any problems here.

To make my point more clear: I don't advocate allowing everybody to use JavaScript in CQ content. For example at the moment we would be perfectly fine with disabling inline JavasScript but allowing our own custom tags. However we would like to make this decision ourselves and even on a per account basis.

jvdkolk’s picture

Just for the sake of documentation: if the ignorant student would insert HTML taken directly from the URL (so without sanitizing), this would allow a third 'evil' student to create evil links. These links he could send to teachers, to steal sessions, etc.

In a reflected XSS attack, the attack is in the request itself (frequently the URL) and the vulnerability occurs when the server inserts the attack in the response verbatim or incorrectly escaped or sanitized. The victim triggers the attack by browsing to a malicious URL created by the attacker. In a stored XSS attack, the attacker stores the attack in the application (e.g., in a snippet) and the victim triggers the attack by browsing to a page on the server that renders the attack, by not properly escaping or sanitizing the stored data.

http://google-gruyere.appspot.com/part2#2__reflected_xss

To make my point more clear: I don't advocate allowing everybody to use JavaScript in CQ content.

Indeed, so for me, I would have no problems with including this option (given a nice big warning is given).

jvdkolk’s picture

Issue summary: View changes

Defined script tags as code

jvdkolk’s picture

Issue summary: View changes
Status: Needs review » Closed (fixed)