Is jQuery .text() method XSS safe?
Solution 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<
for<
)
So yes, it should be safe. Here's your example in jsfiddle. Notice how the tags appear as literal text.
Solution 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('<test>a&f"#</test>');
Solution 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.
Solution 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
Comments
-
Vytautas almost 2 years
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?
-
Vytautas about 12 yearstext not stripping anything just escaping so the result would be
<test>a&f"#</test>
-
mas-designs about 12 yearsdo you have a proof for that ? Because I have used .text() many many many times and it always worked for me.
-
mas-designs about 12 yearsOkay, than this only works for real jQuery Objects to extract the text from the elements.
-
user over 9 years+1 This is quite important and often overlooked. To summarize :
JQuery text() returns unescaped payload which can result in the execution of malicious script if it's passed on to .after() or append() etc. methods
-
Andy Burton over 6 yearsNote that this function also does the reverse - so calling it on already escaped data will result in it being unescaped which can inadvertently result in an XSS - E.g. jsfiddle.net/7ykbosas/1
-
Abhishek almost 5 yearsMinor point of order,
createTextNode
does not "escape all special characters". You're already telling the browser that this is inert text, it doesn't have to escape anything, it simply doesn't run it through any code paths that could possibly execute anything.