在没有任何验证的情况下使用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)攻击? 如果是,那怎么样?攻击者如何才能使用&#34; window.location.href = value&#34;执行XSS?
答案 0 :(得分:17)
使用location.href
可以理解为包含两件事:
location.href
的值,在代码中传递它,操纵它并使用它来指导代码中的逻辑。location.href
,导致浏览器导航到不同的网址。使用该值的第一个可以被认为是安全的。 location.href
的值只不过是一个字符串。当然,它是用户输入的一部分,因此您不希望将其传递给eval
语句,但对于所有其他形式的用户输入也是如此。实际上,location.href
的值始终是有效的URL,因此可以对其内容进行某些假设。从这个意义上说,你可以认为它比其他形式的用户输入安全更多。只要你做出任何错误的假设。
第二个是你应该小心的。为其分配未经验证的值可能会导致可用于网上诱骗的开放重定向以及使用javascript:
和vbscript:
URI引起的XSS问题。
修改:根据要求,以下是对location.href
分配问题的更深入解释:
假设你有一个攻击者控制的变量foo
。它的来源可以是任何东西,但查询字符串参数是一个很好的例子。当您将foo
的值分配给location.href
时会发生什么?好吧,浏览器尽力将该值解释为URI,然后将用户重定向到结果地址。在大多数情况下,这将触发页面加载;例如如果value
为"https://www.google.com/"
,则会加载Google的首页。允许在没有用户交互的情况下发生这种情况称为open redirect,并且被视为安全漏洞!
然而,有些类型的URI不会触发页面加载。这种URI的一个常见例子是只包含片段标识符的URI,例如, #quux
。将其分配给location.href
会导致页面滚动到ID为&#34; quux&#34;的元素。什么都不做只要您不对片段本身的值做任何愚蠢的事情,片段URI就是安全的。
然后到有趣的部分:javascript:
和vbscript:
URI。这些都会咬你。 JavaScript和VBScript URI方案是非标准URI方案,可用于在当前打开的网页的上下文中执行代码。听起来很糟糕,不是吗?好吧,它应该。考虑我们的攻击者控制的变量foo
:攻击者必须做的就是对用户发起攻击是在变量中注入脚本URI。当您将其分配给location.href
时,它与在脚本上调用eval
基本相同。
JavaScript URI适用于所有现代浏览器,而VBScript仅限IE,并且要求页面以怪癖模式呈现。
最后,还有一个有趣的URI方案需要考虑:数据URI。数据URI是文件文字:整个文件编码为URI。它们可用于编码任何文件,包括HTML文档。与其他文档一样,这些文档可以包含脚本。
大多数浏览器将每个数据URI视为自己唯一的origin。这意味着包含在数据URI中的HTML文档中的脚本无法访问其他页面上的任何数据。除了Firefox。
Firefox对数据URI的处理方式与其他所有浏览器略有不同。其中,数据URI 继承打开它的任何文档的来源。这意味着任何脚本都可以访问引用文档中包含的数据。那就是你的XSS。
答案 1 :(得分:1)
#1
下无法使用XSS我能想到的最糟糕的情况是有人使用它进行社交工程(假设您的域名非常受欢迎,如Ebay或亚马逊),攻击者可以做的就是制作一条消息,说出类似于&#34; Amazon / Ebay免费的东西,只需转到http://haxor.site&#34;使用URL并将其发送给某人。
但我仍然觉得它很危险,因为URL编码信息看起来很混乱。
编辑: 这只回答#1,因为当我回答这个问题时,并没有#34;#2&#34;
答案 2 :(得分:0)
var value = getQueryString('url');
window.location.href = encodeURI(value);
我认为这是最简单的方法