Can we remove the PSL dependency?

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