views:

75

answers:

2

Hello I'm having XSS Vulnerability using jQuery's .append() function

what I'm doing is appending raw chat messages coming from users and I don't want to strip html tags serversided or clientsided I just want to display them. Yet jquery's .append() method renders the html markup.

anyway to do like appendText()? I tried .text() but it doesn't work properly generating the proper html.

I currently use.

  var li = $('<div></div>').addClass('chatmsg');
  var al = $('<span></span>').addClass(chatClass).text("You");
  li.append(al);
  li.append(" " + msg);
  $('.chat').append(li);

How can I fix the li.append(" " + msg);

line to ignore rendering html thank you, without anything advanced like regular expressions and such.

Thanks

+1  A: 

You can change it just a bit, like this:

var li = $('<div />', { text: ' ' + msg, 'class': 'chatmsg' });
var al = $('<span />', { text: 'You', 'class': chatClass });
li.prepend(al);
$('.chat').append(li);

This is calling .text() under the covers, encoding anything that might be in msg.

Nick Craver
I once heard that @Nick Craver owns the **jQuery** tag.
Marko
@Marko - most answers *definitely* != owning, and don't let the heavy posters in *any* tag tell you different :) There are lots of smart people in all of the major tags :)
Nick Craver
Thanks alot Nick i'm pretty dumb coder it pisses me off sometimes but thanks to people like you and communities like stackoverflow making my life easier and learning these newer shorthand tricks in the process
SSpoke
@SSpoke - glad we can help :) that really is what it's all about, helping you and the next googler with the same woes that arrives here, love to hear that it's working.
Nick Craver
Wow Nick, KennyTM and Fabian I thought using tags like <div/> is only for tags like input br and etc which don't have closing tags but somehow jquery detects all that yah?
SSpoke
@Nick - Have you thought about writing a book on jQuery? Do you have a blog?
Marko
@Marko - Maybe after the wedding when I have chunks of time available, answering questions is really quick, but the next release for work and wedding stuff at night are eating the vast majority of my time currently :)
Nick Craver
@SSpoke - Yup, there was a shortcut added as well that makes this much faster in recent releases as well.
Nick Craver
+2  A: 

You can use the following function:

function htmlEncode(value){ 
  return $('<div/>').text(value).html(); 
}

So your code becomes:

  var li = $('<div></div>').addClass('chatmsg');
  var al = $('<span></span>').addClass(chatClass).text("You");
  li.append(al);
  li.append(" " + htmlEncode(msg));
  $('.chat').append(li);
Fabian
Better use a `$('<span/>')` instead of `$('<div/>')`, to keep the original appearance. (And why not just `htmlEncode(" " + msg)`? Then you can return the jQuery object directly.)
KennyTM
If you're going to write another method, why not write an `.appendText()` method? I don't understand why you'd rebuild something already in the library...
Nick Craver
but isn't appendText part of some jquery plugin not actually jquery? meaning i have to use another javascript script as well. But thanks Nick Craver i like your method and thanks Fabian thats cool too
SSpoke