- From: Tyler Close <tyler.close@gmail.com>
- Date: Mon, 9 Apr 2012 14:50:56 -0700
On Sat, Apr 7, 2012 at 10:17 AM, Ian Hickson <ian at hixie.ch> wrote: >> > In the case of window.open, it's true that the opener could have >> > navigated by the time you try to communicate back. That's a general >> > problem with window.open(), though; it's not specific to >> > register*Handler(). The solution is to not use window.open(), which is >> > in any case bad UI. >> >> A top-level window is the only context in which you can ask the user to >> engage in security-sensitive interaction, like entering a password, or >> making a selection that must not be vulnerable to clickjacking. > > Then, again, we should fix this at the window.open() level, not the > handler level. It's not a problem specific to register*Handler(). > > The simplest way to address this, which doesn't require any spec changes, > is for the opener to tell the window what origin to use, e.g. by opening > an iframe to do the work and then having the iframe pop up the window, The browser's popup blocker would block that interaction, unless you require an additional click inside the iframe. UX people are generally fanatical about eliminating extra user clicks. >> >> > For such an example, you can just use a fallback section in the >> >> > appcache manifest. (Or a fragment identifier, indeed.) >> >> >> >> Right, the obvious thing to do is use the fragment identifier, but >> >> that's got some security problems. With a small tweak we can make >> >> this safe and easy. >> > >> > I don't understand the security problem. Could you give a concrete >> > example of an attack scenario? >> >> It is well-understood that URL fragment messaging is vulnerable to >> tampering between windows or frames in the browser. Boris already posted >> further clarifying this point and you seemed to understand. I don't know >> what you're confused about. > > I agree that there are ways to use Web technologies that are unsafe. For > example, you could just allow people to inject arbitrary markup into your > page. > > What I do not understand here is what the attack scenario is that is > specific to register*Handler(), if there is one. For RPH to be used in an offline scenario, the %s argument is put in the URL fragment component of the RPH handler's URL. This means the client page is sending data to the RPH handler using URL fragment messaging. So: offline RPH uses URL fragment messaging. URL fragment messaging is vulnerable to tampering. So, I'm asking that we provide a tamper-proof channel for the client to send data to the RPH handler: namely a new DOM field. Here's another concrete attack scenario showing how this vulnerability could be exploited in a mailto RPH handler. Consider a site that requires a user to confirm a security sensitive operation by sending an email with a confirmation number in the Subject field. The site expects this email to be signed by the user's mail software. The web page that sets up this user interaction includes a mailto link to open a pre-populated email editor. This mailto: link includes a subject parameter that contains the confirmation number. The attacker has previously setup an operation that is waiting on such an email confirmation from the victim user. The attacker has additionally lured the user into browsing the legitimate site in a window that the attacker has a reference to. The attack page waits for an iframe to show up in the legitimate site's frame hierarchy at the place where a mailto RPH confirmation action is being done. The attack page overwrites the iframe's URL fragment with a mailto URL that contains a subject parameter specifying the confirmation number for the operation setup by the attacker, instead of the one that the victim user was setting up. The user sends the email, confirming the attacker's operation, instead of their own. From the user's perspective, they see that they are at the legitimate web site and they setup an operation in the normal way which, as expected, opens an email editor with a confirmation number. The user typically never looks closely at the confirmation number, it's just some number chosen by the legitimate web site. So, everything looks normal to the user. From the perspective of the RPH handler page, everything also looks normal. It opens and finds a mailto URL in the %s position in it's URL fragment. It has no idea that the URL fragment has changed since the legitimate site first specified it. We can fix this by putting the %s data in a DOM field that cannot be overwritten by an attacker in this way. Consequently, the legitimate site can securely pass a confirmation number to the RPH handler. The attacker can still navigate to the mailto URL from one of the attacker's own pages, but can't do it from one of the legitimate site's pages. So the attacker can't make it look like the legitimate site is asking the user to send the confirmation email. The important thing to understand here is that a communication channel that is vulnerable to tampering can be abused in unexpected ways. Rather than quibble about how a future attacker might make use of this vulnerability in some future application, the right thing to do is eliminate the vulnerability. It's never a good idea to create an API that relies on a channel vulnerable to tampering, especially when there's no cost to replacing the vulnerable channel. It's an easy fix to specify and implement and it also makes the API easier to use, since the RPH handler no longer needs to parse the URL fragment in its window.location.hash to find the %s data. --Tyler
Received on Monday, 9 April 2012 14:50:56 UTC