Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it really insecure to build HTML strings in Javascript?

The company who hosts our site reviews our code before deploying - they've recently told us this:

HTML strings should never be directly manipulated, as that opens us up to potential XSS holes. Instead, always use a DOM api to create elements...that can be jQuery or the direct DOM apis.

For example, instead of

this.html.push( '<a class="quiz-au" data-src="' + this.au + '"><span class="quiz-au-icon"></span>Click to play</a>' ); 

They tell us to do

var quizAuLink = $( 'a' ); quizAuLink.addClass( 'quiz-au' ); quizAuLink.data( 'src', this.au ); quizAu.text( 'Click to play' ); quizAu.prepend( '<span class="quiz-au-icon"></span>' ); 

Is this really true? Can anyone give us an example of an XSS attack that could exploit an HTML string like the first one?

like image 470
And Finally Avatar asked Nov 18 '14 09:11

And Finally


People also ask

How do developers construct HTML with JavaScript?

Let’s take a look at some of the ways that developers construct HTML with JavaScript ( without using some sort of template library, because lets face it, if you’re using a templating library, you’re probably not interested in this topic). Often, developers will create one big string by concatenating HTML inside of a loop.

Why is it important to build HTML with JavaScript?

Building HTML with JavaScript is important in this day and age, where AJAX is extremely popular and many Internet users have grown used to near-instant UI changes.

How do you create a string in JavaScript?

Normally, JavaScript strings are primitive values, created from literals: let firstName = "John"; But strings can also be defined as objects with the keyword new: let firstName = new String ("John");

Can a string be an object in JavaScript?

Strings Can be Objects. Normally, JavaScript strings are primitive values, created from literals: var firstName = "John"; But strings can also be defined as objects with the keyword new: var firstName = new String("John");


1 Answers

If this.au is somehow modified, it might contain something like this:

"><script src="http://example.com/evilScript.js"></script><span class=" 

That'll mess up your HTML and inject a script:

<a class="quiz-au" data-src=""><script src="http://example.com/evilScript.js"></script><span class=""><span class="quiz-au-icon"></span>Click to play</a> 

If you use DOM manipulation to set the src attribute, the script (or whatever other XSS you use) won't be executed, as it'll be properly escaped by the DOM API.


In response to some commentators who are saying that if someone could modify this.au, surely they could run the script on their own: I don't know where this.au is coming from, nor is it particularly relevant. It could be a value from the database, and the DB might have been compromised. It could also be a malicious user trying to mess things up for other users. It could even be an innocent non-techie who didn't realize that writing "def" > "abc" would destroy things.


One more thing. In the code you provided, var quizAuLink = $( 'a' ); will not create a new <a> element. It'll just select all the existing ones. You need to use var quizAuLink = $( '<a>' ); to create a new one.

like image 195
Scimonster Avatar answered Sep 25 '22 10:09

Scimonster