不经验证直接使用 window.location.href 是不是安全

Posted

技术标签:

【中文标题】不经验证直接使用 window.location.href 是不是安全【英文标题】:Is it secure to use window.location.href directly without validation不经验证直接使用 window.location.href 是否安全 【发布时间】:2014-07-27 12:25:01 【问题描述】:

在没有任何验证的情况下使用 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?

【问题讨论】:

window.location.href 是一个字符串。字符串是无害的,除非你对它们做一些可能有害的事情(innerhtml也许,...或eval 攻击者能否修改window.location.href的值?因为如果他们能够这样做,我认为这是危险的。例如,如果他们可以更改 window.location.href 的内容,他们可能会将其更改为 ")alert("注入成功!")//" 你认为这会实现什么? Have you tried it? 我不知道,我只是想知道他们是否可以改变 window.location.href 的值。 那你就有问题了,因为有人可以通过&lt;script&gt;alert('Haaaaax!');&lt;/script&gt; 【参考方案1】:

使用location.href可以理解为包括两件事:

    通过在代码中传递 location.href 的值、对其进行操作并使用它来指导代码中的逻辑,从而使用它。 为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 的首页。允许在没有用户交互的情况下发生这种情况称为open redirect,并被视为安全漏洞!

但是,有些 URI 类型不会触发页面加载。这种 URI 的一个常见示例是只包含片段标识符的 URI,例如#quux。将其分配给 location.href 将导致页面滚动到 ID 为“quux”的元素,并且不执行任何其他操作。只要您不对片段本身的值做任何愚蠢的事情,片段 URI 就是安全的。

然后是有趣的部分:javascript:vbscript: URI。这些是会咬你的。 JavaScript 和 VBScript URI 方案是非标准 URI 方案,可用于在当前打开的网页的上下文中执行代码。听起来很糟糕,不是吗?嗯,应该的。考虑我们的攻击者控制的变量foo:攻击者要对您的用户发起攻击所要做的就是将脚本 URI 注入变量中。当你把它赋值给location.href时,基本上和在脚本上调用eval是一样的。

JavaScript URI 可在所有现代浏览器中使用,而 VBScript 仅适用于 IE,并且需要以 quirks 模式呈现页面。

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

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

Firefox 处理数据 URI 的方式与所有其他浏览器略有不同。在其中,数据 URI 继承打开它的任何文档的来源。这意味着任何脚本都可以访问引用文档中包含的数据。这就是你的 XSS。

【讨论】:

我对你关于 XSS 的第二个解释很感兴趣。您能否详细解释一下并举例说明 XSS 攻击如何基于这种情况进行?例如, 假设我有一个函数 getQueryString() 将在没有验证的情况下返回值。只是“window.location.href = value”会导致XSS? 用更多细节编辑了答案。 谢谢,您的解释很清楚,很有帮助。非常感谢。 考虑检查 security.stackexchange.com/questions/95362/… 有 2 个使用 javacscript:alert('xss') 的有效 XSS 攻击示例【参考方案2】:

#1 下不可能出现 XSS

我能想到的最糟糕的情况是有人将其用于社会工程(假设您的域像 Ebay 或 Amazon 一样非常受欢迎),攻击者可以做的是制作一条消息,例如“Amazon/Ebay 免费的东西你,只需使用 URL 转到 http://haxor.site" 并将其发送给某人。

但我仍然认为它并不危险,因为 URL 编码的消息看起来很混乱。

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

【讨论】:

【参考方案3】:
var value = getQueryString('url'); 

window.location.href = encodeURI(value); 

我认为这是最简单的方法

【讨论】:

这不适用于 checkmarx 等安全工具。 问题是询问安全原因

以上是关于不经验证直接使用 window.location.href 是不是安全的主要内容,如果未能解决你的问题,请参考以下文章

javascript window.location.href下载问题

我可以在不滚动网页的情况下更新 window.location.hash 吗?

在微信浏览器中 location.reload() 不刷新解决方案(直接调用方法)

关于微信端不支持window.location.reload()

window.location.href下载??

react中为啥不window.location.href来跳转,还要用react-router来跳转