Mando Madalin Mando Madalin - 1 month ago 9
jQuery Question

Why jQuery .val() don't encode & to &

<input type="text" id="search" value=" &amp; ">


When loading page input will show & (that's good)

But if i use jQuery to update value of my input, lets say:

$("#search").val(" &amp; ");
the input will show me
&amp;
(but i want to show & (but still encoded as
&amp;
in the back, like the first example))

What i m missing here?

Answer

You cannot protect yourself against XSS attacks solely by defending yourself against harmful user coding in the browser. I can send you a harmful request even without a browser. You need to protect yourself against XSS attacks on server-side either when you store user data or when you generate the html, depending on your approach.

This is a PHP function with which you can protect yourself against such attacks:

public static function protectArrayAgainstXSS(&$arr) {
    $changed = false;
    foreach ($arr as $index => $a) {
        if (is_array($a)) {
            $changed = $changed || Common::protectArrayAgainstXSS($arr[$index]);
        } else if ($a !== null) {
            $changed = $changed || ($arr[$index] === strip_tags($a));
            $arr[$index] = strip_tags($a);
        }
    }
    return !$changed;
}   

Your code should run this whenever it wants to guarantee that the generated HTML is safe.

As about your question about jQuery: .val() is not supposed to handle what you want. If you want to encode-decode things, you can do something like this:

function htmlEncode(value){
  //create a in-memory div, set it's inner text(which jQuery automatically encodes)
  //then grab the encoded contents back out.  The div never exists on the page.
  return $('<div/>').text(value).html();
}

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

function myVal(context, v) {
    return v ? context.val(htmlEncode(v)) : htmlDecode(context.val());
}

Source.

But whenever you need protection you need to have one at server-side. You can protect your client-side as well against XSS input, but that is optional.