不经验证直接使用 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 的值。
那你就有问题了,因为有人可以通过<script>alert('Haaaaax!');</script>
【参考方案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() 不刷新解决方案(直接调用方法)