关于XSS的一些澄清

Ebb*_*ham 8 javascript java xss jquery

我碰巧读到了关于XSS以及如何避免它.根据我的阅读,我发现我们需要输入过滤,正确处理应用程序代码和输出编码,以使Web应用程序在某种程度上是XSS安全的.经过几篇文章后,仍有几个疑点仍然存在.

  • 当我尝试jQuery.text("untrusted_data")element.text = untrusted_data时,浏览器似乎正在完美地编码内容,但我已经在其他地方读过客户端编码不应该被信任而你必须" 总是 "在服务器端编码.为什么客户端编码被认为不安全?

  • 每当我尝试使用jQuery.val(untrusted_data)element.value = untrusted_data设置值时,它似乎足够安全.那么它真的是XSS安全还是我错过了这里的任何案例?

  • 此外,我碰巧在某处读到jQuery.setAttribute(attrName,untrusted_data)setAttribute(attrName,untrusted_data)通常只有在属性名称不包含基于URL上下文的属性(src,href等)或事件处理程序时才被认为是安全的( onClick,onMouseOver等).如果是这种情况,我应该如何使用setAttribute("href",untrusted_data)设置href属性?来自服务器端的encodeForHtmlAttribute(untrusted_data)是正确的方法吗?
  • 我该如何处理动态html创建.考虑下面的例子

<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
}
Run Code Online (Sandbox Code Playgroud)

我想在这里实现的是从divName1获取文本并将其粘贴到divName2的内容.我上面写的代码是XSS易受攻击的.我可以改成这个

jQuery的( "#divName2").文本(divValue)

因此,这将确保编码,但据我所知,我们说客户端编码是不安全的,只应使用服务器端编码.如何在不使用客户端编码的情况下将其写为XSS安全?我在这里有点困惑:(.请帮我解决这些疑惑.

Mik*_*uel 8

这是很多问题.

为什么客户端编码被认为不安全?

只要正确且一致地完成,客户端编码就可以了.客户端编码通常具有较低的标准,因为它不需要担心像UTF-7攻击这样的字符编码级攻击.

每当我尝试使用jQuery.val(untrusted_data)或element.value = untrusted_data设置值时,它似乎足够安全.那么它真的是XSS安全还是我错过了这里的任何案例?

假设untrusted_data是一个字符串,并且其值正在设置的元素是流或块元素中的常规文本节点,那么你没问题.如果正在分配其值的节点是<script>元素中的文本节点或URL,事件处理程序或样式属性节点或与之相关的任何内容,则可能会遇到麻烦<object>.

此外,我碰巧在某处读到jQuery.setAttribute(attrName,untrusted_data)和setAttribute(attrName,untrusted_data)通常只有在属性名称不包含基于URL上下文的属性(src,href等)或事件处理程序时才被认为是安全的( onClick,onMouseOver等).如果是这样的话,

这部分是正确的.其他属性有锐利的边缘style和许多与<object><embed>,和<meta>.

如果您对该属性了解不多,则不要将其暴露给不受信任的数据.通常安全的东西是包含文本内容的属性title,或者包含类似dir=ltr和的枚举值的属性dir=rtl.

一旦你处理那些需要你在攻击者利用模糊的浏览器扩展喜欢的风险更复杂的值的属性-moz-bindingstyle属性.

它似乎足够安全

地雷似乎是安全的,直到你踩到它们.

你不能从"看似安全"的东西中得出很多结论.你确实需要查看它并理解可能出现的问题,并安排事情,以便只有在出现完美风暴的情况下才能处于危险之中(P(灾难)= P(失败0)*P(失败1) )*...)并且当只有一件事出错时你没有风险(P(灾难)= P(失败0)+ P(失败1)*P(!failure0)+ ...).

我应该如何使用setAttribute("href",untrusted_data)设置href属性?

如果没有将协议列入白名单,请不要这样做.

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

来自服务器端的encodeForHtmlAttribute(untrusted_data)是正确的方法吗?

编号传递给的值的HTML setAttribute是多余的,无助于保留任何安全属性. <iframe srcdoc>可能是一个罕见的例外,因为如果我对最近的规范更改的回忆是正确的,那么它的内容就是HTML.

我想在这里实现的是从divName1获取文本并将其粘贴到divName2的内容.我上面写的代码是XSS易受攻击的.

不要乱用HTML.浏览器的.innerHTMLgetter是有缺陷的,有时会导致漏洞利用,就像在IE中作为值分隔符的反引号一样.只需将节点从一个克隆到另一个.像下面这样的东西应该这样做:

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

我可以改成这个

jQuery("#divName2").text(divValue)
Run Code Online (Sandbox Code Playgroud)

如果你想要的只是文字内容那就没关系.

  • "在你踩到它们之前,地雷似乎是安全的.这是我遇到的任何类型的IT安全问题的最佳总结,其中提议的解决方案'似乎足够安全'...... (2认同)