0

I follow the WP philosophy of late escaping, but I'm not sure when to escape HTML special characters when working with ajax requests.

Note, as of my understanding, when setting data to an element with the jQuery .text() method, or using createTextNode()` method, it automatically escapes text content. So this question doesn't apply to using those methods.

When setting text content to an element with innerHTML property or jQuery .html() method after an ajax request, is it better to escape the text content with js, or is it better to escape the text content on the server side with esc_html()?

Here are two examples, I'm not sure what the best one is:

Escapaing server side before sending to client:

// PHP

// Final stage of processing the ajax request (server side).
echo esc_html($text);
die();


//JS (jQuery)

// Final stage of a JS ajax request
success: function(response) {
    $('.example').html('<div class="example">' + response + '</div>'); // The response is already escaped
}

Or Escaping with JS after the ajax request was successful:

// PHP

// Final stage of processing the ajax request (server side).
echo $text;
die();


//JS (jQuery)

/**
 * Example of my js html escape function
 */
function escapeHtml(unsafe) {
    return unsafe
         .replace(/&/g, "&amp;")
         .replace(/</g, "&lt;")
         .replace(/>/g, "&gt;")
         .replace(/"/g, "&quot;")
         .replace(/'/g, "&#039;");
 }

//Final stage of a JS ajax request
success: function(response) {

    // Escape the untrusted data
    $('.example').html('<div class="example">' + escapeHtml(response) + '</div>'); // The response needs to be escaped
}

Any help appreciated.

1 Answer 1

2

If it is not HTML, it does not need HTML escaping, if it is not JS, it does not need JS escaping.

All escaping is context based. In general You should probably just avoid sending "text" in response and focus on sending data which is "converted" into whatever is the relevant DOM structures, either directly via DOM APIs or the roundabout ways jQuery offers. (in other words, your ajax response should be aimed at machines, and let the end machine to transform it to something which is readable by humans).

Still there are cases in which is more convenient to add full blown HTML texts to the response. If you go in that direction, the escaping should be relevant to how you are going to handle it on the browser side. jQuery's html() expects a valid HTML therefore you will have to escape the textual parts of the HTML that you generate. DOM APIs might be more tolerant as depending on context they "know" what is an HTML tag and what is a text.

In any case I can't think of any example in which you will have to do escaping on browser side. If you get yourself into such situation, you probably use the wrong DOM/jQuery APIs.

Commenting directly on your samples. The first one is wrong because if the text contains HTML tags, you will be escaping too much.

3
  • I never want to send data with HTML tags to the response. I either send just text or json encoded array of non-HTML data. But HTML tags/special characters can sometimes get into my data such as __('a translator can XSS'). So at some point it needs to be escaped. Then on the JS side, I sometimes want to use .html() or similar because there are times I want to build up some HTML in the JS file, add response data inside that HTML then add the whole HTML block with .html(). So the response data needs to be escaped at some point, which is why my 2 examples will work. Commented Sep 23, 2017 at 11:13
  • which is why you should not send "text" in the first place in a response. If a translator is suspicious (for whatever value of the word) don't use __ but esc_html__ or apply one of the kses functions on the translation depending if you want to let him have the ability to add some tags or not. This part of your comment is more about how to handle translations than beeing specific to AJAX. Commented Sep 23, 2017 at 12:54
  • now if you "sometimes" want to use html and sometime want to do other things, the problem is basically with the inconsistency of how you handle the AJAX response, and you will not be able to solve it in any way. You will either need to be consistent or have two different AJAX request, or two "values" in each response Commented Sep 23, 2017 at 12:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.