With the increasing use of Ajax to handle the majority of the data transfer between web pages and the server, there are a number of occasions where the server needs to return a JSON response to the page, which will be intercepted by some Javascript, and parts of that response will be injected into the page as new chunks of HTML for display.

This means that any potentially dangerous (user entered) text which is stored and displayed needs to be escaped properly in at least 4 places:

  1. when the text is sent to the server - escaped and validated for sending via a POST request
  2. when the text isadded to the database - escaped and wrapped to prevent SQL injection
  3. when the text is added to the JSON response - escaped to produce valid JSON
  4. when the text is inserted into the relevant div/span on the page - escaped to prevent XSS

This blog post is purely about an easy way to handle the last one. Our example bad POST parameter is:

dodgyMessage=<marquee>Bad Things!</marquee>

Our example JSON response is:

{ "message" : "${hisl:escapeJson(dodgyMessage)}" }

(Notice that we use hisl:escapeJson() to handle the 3rd type of escaping) This gets back into our Javascript which looks something like:

$.post( url, params, function(data) {
    if (validResponse(data)) {
        $("div#fancyMessageBox").html(data.message);
    } else {
        // handle bad things
    }
});

This code uses the JQuery html() method to ensure that any HTML entities and quoting are correctly handled. However this doesn't appear to stop valid HTML tags being passed through. So at the moment we'd see our fancyMessageBox showing a scrolling "Bad Things!" message. A simple fix is to combine the JQuery text() and html() methods so the javascript instead looks like:

$.post( url, params, function(data) {
    if (validResponse(data)) {
        $("div#fancyMessageBox").text(data.message).html();
    } else {
        // handle bad things
    }
});

The only caveat with this trick appears to be that it may not preserve whitespace like tabs and newlines in your messages.

Next Post

© Me. Best viewed with a sense of humour and a beer in hand.