Is jQuery .text() method XSS safe?

2019-03-09 05:54发布

问题:

I have unescaped data from users.

So is it safe to use like this:

var data = '<test>a&f"#</test>'; // example data from ajax response
if (typeof(data) === 'string')
    $('body').text(data);

Can I use like this or there is some problems like encoding or some specific symbols that I should be careful and add more strict validation?

回答1:

When you set the text of an element using the text method, jQuery uses createTextNode internally, which escapes all special characters.

From the jQuery docs:

We need to be aware that this method escapes the string provided as necessary so that it will render correctly in HTML. To do so, it calls the DOM method .createTextNode(), which replaces special characters with their HTML entity equivalents (such as &lt; for <)

So yes, it should be safe. Here's your example in jsfiddle. Notice how the tags appear as literal text.



回答2:

Because XSS attacks rely on being able to insert DOM nodes (<img />, <script />) etc, and jQuery.fn.text() does not support this, it is entirely XSS safe.

As you can see in this basic example, all would-be-HTML tags are encoded as a result of jQuery using createTextNode internally:

jQuery('div').text('<test>a&f"#</test>');​

So that what is actually inserted is more equivilant to;

jQuery('div').html('&lt;test&gt;a&f"#&lt;/test&gt;');​


回答3:

You still have to be careful when inserting the result into the DOM - see: Cross-Site Scripting vulnerability with JavaScript and JQuery.

For setting the text of elements, however, text should be XSS safe.



回答4:

The author from http://benv.ca/2012/10/02/you-are-probably-misusing-DOM-text-methods/ argues against using createTextNode or jQuery's .text().

...if you know the context in which you are injecting the value (i.e. not attributes), then this method is safe. My argument is that developers don’t understand those contexts well enough, and sooner or later they will get it wrong.

It is better to use string replacement (of at least <).

Some examples from well-secured libraries:

  • Mustache https://github.com/janl/mustache.js/blob/master/mustache.js#L55
  • Angular https://github.com/angular/angular.js/blob/v1.3.14/src/ngSanitize/sanitize.js#L438

The #1 OWASP suggestion is:

RULE #1 - HTML Escape Before Inserting Untrusted Data into HTML Element Content



回答5:

Unlike the .html() method, .text() can be used in both XML and HTML documents. The result of the .text() method is a string containing the combined text of all matched elements. (Due to variations in the HTML parsers in different browsers, the text returned may vary in newlines and other white space.)

.text(data) would strip the <test></test> away and leave you with a&f#



回答6:

Yes. It deals in text, not code.