1

I store unsanitized user input in my database, then escape it on output.

If I enter "><svg/onload=alert(3)> into an input and save it in the database, then load a page that escapes the data, putting it back into the input, the page source shows:

... value="&quot;&gt;&lt;svg/onload=alert(3)&gt;" ...

As you can see, it's escaped.

However, If I then run this code:

$(".somediv").html($("#myinput").val());

Then the following is put into the element:

""><svg/onload=alert(3)>"

And the alert box pops up.

JSFIDDLE

What am I doing wrong here? I thought escaping my data on output was all I needed to do, but apparently when manipulating the DOM with jQuery that's not true.

Nate
  • 26,164
  • 34
  • 130
  • 214
  • http://stackoverflow.com/questions/1219860/html-encoding-in-javascript-jquery – Jimmy Chandra Apr 09 '15 at 00:06
  • 1
    you can use `div.innerHTML=str` instead of `$(div).html(str)` to avoid execution of scripts and keep formatting, but you still need to watch for inline event handlers. – dandavis Apr 09 '15 at 01:37

1 Answers1

4

If you want to set text, use .text(). The entities in the attribute’s value are already interpreted, and ""><svg/onload=alert(3)>" is the value of the attribute.

$(".somediv").text($("#myinput").val());

$('#destination').text($('#source').attr('title'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="source" title="&amp;&quot;&lt;">Hover over me!</div>

<div id="destination"></div>
Ry-
  • 218,210
  • 55
  • 464
  • 476