直接使用window.location.href而不进行验证是否安全?

30

使用window.location.href而不进行任何验证是否安全?

例如:

<script>
    var value = window.location.href;
    alert(value);
</script>

从上面的例子来看,它是否容易受到跨站脚本攻击(XSS)? 如果是,那么攻击者如何修改window.location.href的值为恶意内容?

编辑(第二种情况)

这是网址:www.example.com?url=www.attack.com

假设我有一个getQueryString()函数,它将返回未经验证的值。

<script> 
    var value = getQueryString('url'); 
    window.location.href = value; 
</script>

同样的问题,它是否容易受到跨站脚本攻击(XSS)的攻击? 如果是,那么如何?攻击者如何利用“window.location.href = value”执行 XSS 攻击?


4
window.location.href是一个字符串。字符串本身并不危险,除非你对它进行一些潜在的危险操作(例如使用innerHTMLeval函数)。 - Niet the Dark Absol
我不知道,我只是想知道他们是否能够更改window.location.href的值。 - overshadow
但这会有什么不同呢? - Niet the Dark Absol
2
那么你会有一个问题,因为有人可以传递<script>alert('Haaaaax!');</script> - Niet the Dark Absol
http://stackoverflow.com/?no-really-you-think-this-is-safe - Niet the Dark Absol
显示剩余4条评论
3个回答

40

使用 location.href 可以理解为包括两个方面:

  1. 在代码中传递、操纵并使用 location.href 的值来指导代码逻辑。
  2. 将某些东西分配给 location.href,导致浏览器导航到不同的 URL。

第一种情况,使用该值可以被认为是安全的。 location.href 的值只不过是一个字符串。当然它是用户输入的一部分,因此您不希望将其传递给 eval 语句,但对所有其他形式的用户输入也是如此。实际上,location.href 的值始终是有效的 URL,因此可以对其内容进行某些假设。在这种意义上,您可以认为它比大多数形式的用户输入更加安全。只要您没有做出错误的假设。

第二个方面需要您小心谨慎。分配未经验证的值可能会导致开放重定向,可用于网络钓鱼,更糟糕的是,由于使用了 javascript:vbscript: URI,可能会引起 XSS 问题。


编辑: 根据要求,以下是有关分配给location.href 的问题的更详细说明:

假设您有一个由攻击者控制的变量foo。它的来源可以是任何东西,但查询字符串参数是一个很好的例子。当您将foo的值分配给location.href时,会发生什么?好吧,浏览器会尽力将该值解释为URI,然后将用户重定向到结果地址。在大多数情况下,这将触发页面加载;例如,如果value"https://www.google.com/",则会加载Google的首页。允许这种情况在没有用户交互的情况下发生被称为开放式重定向,并且被认为是一种安全漏洞!
但是,有一些类型的URI不会触发页面加载。一个常见的例子是仅包含片段标识符的URI,例如#quux。将其分配给location.href将导致页面滚动到具有ID“quux”的元素,并且不执行任何其他操作。只要不对片段本身的值做出愚蠢的事情,片段URI就是安全的。
现在到有趣的部分:javascript:vbscript: URI。这些是会伤害到您的URI。JavaScript和VBScript URI方案是非标准URI方案,可用于在当前打开的网页上下文中执行代码。听起来很糟糕吧?是的,应该是这样。考虑我们的攻击者控制变量foo:攻击者所要做的就是将一个脚本URI注入变量中,就可以对您的用户发动攻击。当您将其分配给location.href时,基本上相当于在脚本上调用eval
JavaScript URI适用于所有现代浏览器,而VBScript仅适用于IE,并且需要以quirks模式呈现页面。

最后,还有一个有趣的URI方案需要考虑:data URI。Data URI是文件文字:作为URI编码的整个文件。它们可用于编码任何文件,包括HTML文档。而这些文档,像其他任何文档一样,都可以包含脚本。

大多数浏览器将每个data URI视为自己独特的来源。这意味着在data URI中包装的HTML文档中的脚本无法访问其他页面上的任何数据。除了Firefox。

Firefox对待数据URI与所有其他浏览器有所不同。在Firefox中,数据URI会继承打开它的任何文档的来源。这意味着任何脚本都可以访问引用文档中包含的数据。这就是XSS给您带来的问题。


我对你在XSS方面的第二个解释很感兴趣。你能否详细解释一下,并举例说明基于这种情况下XSS攻击是如何进行的呢? 例如,<script> var value = getQueryString('url'); window.location.href = value; </script> 假设我有一个getQueryString()函数,它会返回未经验证的值。仅仅"window.location.href = value"就会导致XSS攻击吗? - overshadow
编辑了答案并添加了更多细节。 - jupenur
谢谢,你的解释清晰而有帮助。非常感激。 - overshadow

2

#1情况下不可能发生XSS攻击。

我能想到的最糟糕情况是有人利用它进行社交工程(比如你的域名像Ebay或Amazon这样非常受欢迎),攻击者可以制作一条消息,说“Amazon/Ebay有免费东西送给你,只需访问http://haxor.site”,并将其发送给某人。

但我仍然认为这不危险,因为由于URL编码,消息看起来会非常混乱。

编辑: 这只回答了#1,因为当我回答这个问题时还没有“#2”


-5
var value = getQueryString('url'); 

window.location.href = encodeURI(value); 

我认为这是最简单的方法


1
这对于像checkmarx这样的安全工具不起作用。 - Asiri Hewage
2
问题是关于安全原因的。 - Saurav
这并不能缓解问题。您需要通过检查诸如javascript:之类的方案来验证value - Allan Guwatudde

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接