- From: Richard Barnes <rbarnes@mozilla.com>
- Date: Thu, 28 Jul 2016 14:38:16 -0400
- To: W3C WebAuthn WG <public-webauthn@w3.org>
- Message-ID: <CAOAcki9dMB79q0K1b6mfUngQM6-dT6uuCaXeZSMBdL1SVe6adg@mail.gmail.com>
Hey folks, One of the things that's bothered me for a while about this spec is that it is dependent on the Public Suffix List (via eTLD+1), a technology that we are trying hard to deprecate. Every other security boundary in the web is origin-based (except for cookies, an anti-pattern), so why not this one? Proposal: RP ID == Web Origin I understand that people want to be able to share credentials across origins to a degree, so that, for example, you could have accounts.example.com make a credential and login.example.com use it. So let's operate under the assumption that if you're going to have a restriction on who can generate an assertion, it would need to accommodate this pattern. Let’s try to articulate the requirements here. For each getAssertion() transaction, there’s a CreatorOrigin that created the credential and an AssertionOrigin that calls getAssertion(). As I understand it, the security requirements are then: - AssertionOrigin can only get an assertion if authorized by CreatorOrigin - If an assertion is generated, it is bound to AssertionOrigin (and/or CreatorOrigin?) The current spec provides a very loose approximation, using possession of the credential ID and belonging to the same eTLD+1 as a proxy for authorization, and using the eTLD as a rough identifer for either origin. - AssertionOrigin can only get an assertion if: - It has a copy of the credential ID - It is in the same eTLD+1 as CreatorOrigin - The eTLD+1 is included in the assertion This is pretty lame sharing model. It unnecessarily places all subdomains of an eTLD+1 at the same trust level. It forbids sharing across the eTLD+1 boundary, even when it's authorized. And it only provides partial information about who generated the assertion. Changing to use the web origin as the RP ID would make this much more faithful. With regard to indicating the AssertionOrigin in the assertion, using the full origin instead of the eTLD+1 obviously provides more information to the verifier. The slightly more interesting question is how authorization gets expressed. I would propose that using possession of the credential ID is a sufficient signal of authorization to use the credential. You get a pretty good level of protection against things like phishing just by having the credential ID not be accessible to unauthorized sites. Even if an unauthorized origin (AttackerOrigin) can get access to a credential ID, e.g., via XSS, every assertion it generates will indicate AttackerOrigin as the AssertionOrigin, so verifiers can easily recognize incorrect ones. The sharing requirements noted above can still be satisfied even if RP ID == Origin. The only modification that’s required is that the verifier has to check the assertion against the AssertionOrigin, instead of the eTLD+1. The AssertionOrigin has to get a copy of the credentialID, but it already had to do that before. If we want to have a more restrained sharing model than just using the credential ID as a bearer token, it seems like there are a few ways you could imagine creating an origin whitelist for a credential. (For example, you could pass the whitelist into makeCredential() and have the credential encode it in the credentialID.) But before we launch into designing this, I would want to know what the threat model is that this would address. Thoughts? --Richard
Received on Thursday, 28 July 2016 18:38:47 UTC