Some clarifications regarding XSS

I happen to read about XSS and how to avoid it. From what I read, I learned that we need input filtering, proper processing of application code and output coding to make the web application somewhat safe for XSS. After going through several articles, some doubts still persist.

  • When I tried jQuery.text ("untrusted_data") or element.text = untrusted_data strong>, the browser seems to be great at coding the content, but I read somewhere that there is no need to trust on the client side, and you need to " always "encode on the server side. Why is client-side encoding considered unsafe?

  • Whenever I tried to set a value using jQuery.val (untrusted_data) or element.value = untrusted_data strong>, it seems quite safe. So is it really XSS safe or am I missing any case here?

  • Also, I read somewhere that jQuery.setAttribute (attrName, untrusted_data) and setAttribute (attrName, untrusted_data) are usually considered safe only if Attribute Names don't include context based attributes based on context (src, href, etc.). etc.) or Event Handlers (onClick, onMouseOver, etc.). If so, how should I set the href attribute using setAttribute ("href", untrusted_data)? Is server side encodeForHtmlAttribute (untrusted_data) the right way to approach?
  • How should I handle dynamic html creation. Consider the example below

<div id="divName1" onClick="copyData()">untrusted_data</div> <div id="divName2"></div>

 function copyData() { var divValue = jQuery("#divName1").html(); jQuery("#divName2").html(divValue);/XSS Here } 

I want to get the text from divName1 here and paste it into divName2. The code I wrote above is vulnerable to XSS. I can change this to

JQuery ("# ​​divName2"). Text (divValue)

This way it will provide encoding, but as I understand it, we say that client-side encoding is unsafe, and only server-side encoding should be used. How should I write this as safe for XSS without using client encoding? I'm a little confused here :(. Please help me resolve these doubts.

+8
java javascript jquery xss
source share
1 answer

These are many questions at once.

Why is client-side encoding considered unsafe?

Client-side encoding is great if it is executed correctly and consistently. Client-side coding is often of lower value, since you do not have to worry about character-level coding attacks, such as UTF-7 attacks.

Whenever I tried to set a value using jQuery.val (untrusted_data) or element.value = untrusted_data, it seems quite safe. So is this XSS safe or have I missed any case here?

Assuming untrusted_data is a string, and the element whose value is set is the regular text node in the stream or block element, then you're fine. You may run into difficulties if the node whose value is assigned is the node text in the <script> element or URL, an event handler, or a node style attribute or something related to <object> .

Also, I read somewhere that jQuery.setAttribute (attrName, untrusted_data) and setAttribute (attrName, untrusted_data) are usually considered safe only if attribute names do not include attributes based on URL context (src, href, etc.) or Event Handlers (onClick, onMouseOver, etc.). If so,

This is partially correct. Other attributes have sharp edges, such as style and many things related to <object> and <embed> , and <meta> .

If you know little about an attribute, do not expose it to untrusted data. Things that are generally safe are attributes that contain text content, such as title , or that have listed values, such as dir=ltr and dir=rtl .

Once you deal with attributes that take on more complex meanings, you risk that attackers use obscure browser extensions such as -moz-binding in style attributes.

it seems safe enough

Land mines seem safe until you step on them.

You cannot make anything out of something "seems safe." You really need to look at this and understand what can go wrong and arrange for you to be at risk only when a perfect storm of things happened (P (catastrophe) = P (failure0) * P (failure1)) * .. .) and that you are not at risk when only one error occurs (P (disaster) = P (fail0) + P (fail1) * P (! failure0) + ...).

how should I set the href attribute using setAttribute ("href", untrusted_data)?

Do not do this without a white protocol.

 if (!/^https?:\/\//i.test(untrusted_data) && !/^mailto:/i.test(untrusted_data)) { throw new Error('unsafe'); } 

Is server side encodeForHtmlAttribute (untrusted_data) the correct way?

Not. HTML encoding the value passed to setAttribute is redundant and does not preserve any security properties. <iframe srcdoc> may be a rare exception, because its contents are HTML, if my recollection of recent changes to the specification is correct.

I want to get the text from divName1 here and paste it into divName2. The code I wrote above is vulnerable to XSS.

Do not guess with HTML. Browsers .innerHTML getters are erroneous, and sometimes this leads to exploits, like backticks acting as value separators in IE. Just clone nodes from one to another. This should do the following:

 var div1 = $('#divName1'); for (var child = div1[0].firstChild(); child; child = child.nextSibling) { $('#divName2').append([child.cloneNode(true)]); } 

I can change this to

 jQuery("#divName2").text(divValue) 

This is great if all you need is text content.

+8
source share

All Articles