2012-11-20 50 views
8

我碰巧了解了XSS以及如何避免它。从我读过的内容来看,我知道我们需要输入过滤,正确处理应用程序代码和输出编码,以使Web应用程序有点XSS安全。在阅读了几篇文章后,仍然存在一些疑问。关于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 
} 

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

的jQuery(“#divName2”)。文本(divValue)

所以,这将确保编码,但我的理解,我们说客户端的编码是不安全并且只应使用服务器端编码。如何在不使用客户端编码的情况下编写XSS以保证安全?我在这里有点糊涂:(。 请帮我清除这些疑虑。

+0

'element.text'本身是安全的,但如果使用字符串插值将数据传递到客户端代码,则可能会遇到问题。 –

回答

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=ltrdir=rtl)的属性。

一旦处理的属性采用更复杂的值,攻击者就有可能利用模糊的浏览器扩展-moz-binding中的style属性。

这似乎是足够安全

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

你不能从“看起来安全”的东西得出多少结论。你真的需要看看它,并且明白什么可能出问题,并且安排一些事情,这样只有当事情出现错误时才会有风险(P(灾难)= P(failure0)* P(failure1 )* ...),并且当只有一件事出错时(P(灾难)= P(failure0)+ P(failure1)* P(!failure0)+ ...),您没有风险。

我该如何通过setAttribute(“href”,untrusted_data)设置href属性?

不要在没有列入白名单的情况下执行协议。

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

是encodeForHtmlAttribute(untrusted_data)从服务器端方法的正确方法?

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

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

不要使用HTML。浏览器的'.innerHTML获取者是有问题的,有时会导致攻击,就像在IE中作为价值分隔符的反引号一样。只需将节点从一个克隆到另一个。像下面的东西应该做到这一点:

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

我可以改变这

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

那很好,如果你想要的是文本内容。

+1

体面的答案。只是为了增加一点 - 就像作者提到的那样,属性也应该被消毒。您可以相对轻松地在服务器端或客户端执行此操作 - 主要难点在于可能对其执行的各种攻击。在过滤脚本的网页上有一些非常好的例子。 –

+2

'地雷似乎是安全的,直到你踩到他们。“这是我遇到过的任何一种IT安全问题的最好的总结,其中提出的解决方案'似乎安全'...... – ppeterka

+0

@Mike非常感谢详细的答案:) –