[whatwg] Fixing two security vulnerabilities in registerProtocolHandler
ian at hixie.ch
Sat Apr 7 10:17:39 PDT 2012
On Fri, 6 Apr 2012, Tyler Close wrote:
> On Fri, Apr 6, 2012 at 3:36 PM, Ian Hickson <ian at hixie.ch> wrote:
> > On Fri, 6 Apr 2012, Tyler Close wrote:
> >> >
> >> > Well if it's an iframe, the parent can't be anything but the
> >> > original origin, as far as I can tell.
> >> What happens if the handler sends the postMessage to "*", then the
> >> parent is navigated? Will the postMessage be delivered or not?
> > A task queued on a Document is associated with that Document and can
> > only be processed when that document is active.
> I'll assume that means it's not delivered, even though postMessage is a
> method on a Window, not a Document.
Yes. See the event loop spec:
Tasks are always associated with a Document, which must be active for them
to be processed.
> > 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, or
by sending the origin in the URL, or using the postMessage() "source"
> >> > 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
What I do not understand here is what the attack scenario is that is
specific to register*Handler(), if there is one.
> >> > Why would a mail client talk back to its opener?
> >> It might not, but some RPH handlers will.
> > Why? What's the use case?
> So, it seems you're arguing that the Mozilla blog post was silly and
> developers won't try to solve problems that way. Is that so?
I haven't read the blog post recently. I am quite willing to believe that
it does things in an insecure manner; that does not, however, imply that
there is not a secure way to do things.
> Well, perhaps it's not strictly necessary for you to understand it.
If you want me to change the spec, I need to understand why.
On Fri, 6 Apr 2012, Tyler Close wrote:
> >>> On Mon, Apr 2, 2012 at 4:39 PM, Ian Hickson <ian at hixie.ch> wrote:
> >>> > On Mon, 26 Sep 2011, Tyler Close wrote:
> >>> For example, a web mail program might have two registered RPH
> >>> handlers for mailto: "https://example.org/?from=me@company&q=%s" and
> >>> "https://example.org/?from=me@personal&q=%s". The user has
> >>> configured their browser to send mailto links to their personal
> >>> email editor. A malicious client page could directly open the URL
> >>> for the company email editor. The web mail editor needs a way to
> >>> detect when a client page is trying to subvert the user's chosen
> >>> preferences. So, an RPH handler needs a way to know that it was
> >>> loaded via the RPH dispatch. Once it knows this, it can also trust
> >>> that the arguments in the URL, such as "from" in this case, were not
> >>> tampered with by the client page.
> >> I don't understand the attack scenario. Sure, a Web page can open
> >> another Web page with arbitrary arguments. Why does it matter here?
> In the example above, the user is expecting that clicking a mailto link
> initiates sending of an email from their personal email account. The
> attack page bypasses the RPH dispatch and directly sends the user to
> their company email editor.
...then the user didn't click on the mailto: link, and the user's
expectation regarding mailto: links is quite irrelevant.
> With the change I am asking for, the mailto RPH handler can detect that
> the RPH dispatch was bypassed and show UI that says: "Hey user, this was
> an unusual request. Are you sure you want to use this account? Maybe you
> want to use one of these others." In the legitimate scenario, the mail
> handler page can assume that the user is using the account they intended
> to, since the browser indicated that this is an RPH request and so this
> handler is the one the user purposely selected.
People use the wrong identity regardless of people trying to trick them
into it, so I don't buy that this is a register*Handler()-specific issue.
If a page really wanted to protect against being invoked directly rather
than through a register*Handler() request, they could just put a key in
their URL, specific to the user, and verify that. But that seems to rather
miss the point of the Web, which is all about allowing links between
In any case, assuming we go with what I proposed in:
...then register*Handler()-triggered page loads will be detectable from
their intent object's value.
Ian Hickson U+1047E )\._.,--....,'``. fL
http://ln.hixie.ch/ U+263A /, _.. \ _\ ;`._ ,.
Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
More information about the whatwg