[Openid-specs-mobile-profile] Account Migration - porting_data with new 'sub', and not looking like id_token

Manger, James James.H.Manger at team.telstra.com
Wed Jun 15 05:13:38 UTC 2016


>> The signed assertion by the old OP that the user has migrated to the new OP does not identify a specific account at the new OP

> What we could consider is to put a user id at the new OP into the porting data (in addition to the issuer). The problem is see is the old OP would need to trust the new OP with respect to these values.

>> If an attacker moved the "porting_data" to their own entry in the new OP’s database, then they can take over the migrated user’s account at the RP

> If an attacker is able to modify the user database, would he not also be able to move the stable sub between user accounts? So same effect?

Consider a malicious user at a Dodgy_OP migrating to OP2, but including porting_data copied from a legitimate port from OP1 to OP2. The spec simply says "the new OP [OP2] associates the migration data [signed by OP1] with the respective local account [of the malicious user]". The malicious user managed to "move the porting_data to their own entry", but didn't need to hack OP2 to do so. One answer to this specific attack is for OP2 to verify that the porting_data sent by Dodgy_OP is signed by Dodgy_OP (not by OP1). But a better answer is probably to make the porting_data more specific by including OP2’s sub in the signed data.



>> The "porting_data" looks like an id_token from the old OP. In fact, it might even be accepted as an id_token by some RPs, which will silently ignore the "migrated_to" element as an unknown element for an id_token. Is that dangerous? I’m not sure; I’m not sure it isn't. We really need an element in the signed data to unambiguously identify the semantics of the message.

> TL: good point - any sugesstions?

For the "porting_data" draft-00 suggests the JWS payload is:
  { iss:…, sub:…, redirect_uri(sic):…, migrated_to:…, exp:…, iat:… }

Suggestion #1: JWS payload is 2-item array, 1st item gives semantics, 2nd item is value:
  [ "porting_data", { <as above> } ]

Suggestion #2: JWS payload has "T" member to state the type of message:
  { T:"porting_data", iss:…, sub:…, … }

Suggestion #3: JWS payload is an object with 1 member whose name gives the semantics:
  { "porting_data": { iss:…, …} }

Suggestion #4: set the 'cty' (content-type) JWS header parameter:
  {"alg":"RS256", "kid":"k5", "cty":"porting_data"} . {iss:…, …}

Suggestion #5: change structure/names in JWS payload:
  { "from":{iss:…, sub:…},
    "to":{iss:…, sub:…},
    … }

Suggestion #6: JWS payload has "@context" member, as specified by JSON-LD (Linked Data) < https://www.w3.org/TR/json-ld/#basic-concepts >:
  { "@context":"https://openid.org/id/porting_data", iss:…, sub:…, … }

Suggestion #7: JSON payload combining #2 (for a long-term solution) and #5 (for a quick fix):
  { "T":"porting_data",
     "from":{iss:…, sub:…},
    "to":{iss:…, sub:…},
    … }

#2 is simplest, but the existing id_token syntax doesn't have an explicit field to indicate its semantics so #2, #4, and #6 don't actually guarantee no misinterpretation. #3 is cute (and Phillip Hallam-Baker’s preferred syntax for JSON messages), but I don't like the fact that there could still be misinterpretations if there is more than 1 element at the top-level. #1 is my choice. #5 is the easiest choice for this specific situation. #7 is okay.

--
James Manger


----------
From: Torsten.Lodderstedt at telekom.de [mailto:Torsten.Lodderstedt at telekom.de] 
Sent: Friday, 10 June 2016 9:23 PM

Hi James,

thanks for your comments. Please find my comments inline (TL:).

----------
Von: Manger, James [mailto:James.H.Manger at team.telstra.com]
Gesendet: Freitag, 10. Juni 2016 05:50

Thanks for writing down a concrete proposal, Torsten. http://lists.openid.net/pipermail/openid-specs-mobile-profile/Week-of-Mon-20160606/000439.html

Some comments:

The signed assertion by the old OP that the user has migrated to the new OP does not identify a specific account at the new OP. It lists the old 'sub', old 'iss' and new 'iss' (in 'migrated_to'). This means this assertion could be used with any account at the new OP, or even with multiple accounts at the new OP. An RP needs to trust the new OP so trusting them to only use the assertion with the correct account might be acceptable. However, it feels like a significantly bigger risk than alternative designs (eg where the 'sub' remains the same at old & new OP).

TL: I understand your feelings but I don't understand why the risk is significantly bigger. But I see the burden it puts on implementations to use the same sub value across OPs. OpenID Connect does not require this for good reasons. Due to the scoping of subs by issuer ids, there is no need to a global schema. Each OP just has to make sure there are no clashes within its namespace. It also ensures every user identity can only be asserted by the owning OP. What we could consider is to put a user id at the new OP into the porting data (in addition to the issuer). The problem is see is the old OP would need to trust the new OP with respect to these values. 

For instance, a "porting_data" value is likely to be sitting in the new OP’s database against a user’s account. If an attacker move the "porting_data" to their own entry in the new OP’s database, then they can take over the migrated user’s account at the RP. It’s an attack, but it might not be as hard as compromising an authentication flow.

TL: If an attacker is able to modify the user database, would he not also be able to move the stable sub between user accounts? So same effect? 

This limitation might be able to be patched if the new 'sub' is also signed. That would require a more complex API: perhaps new OP gets list of 'sector_id's from old OP; then POSTs new 'sub's; which the old OP signs.

If we want to specify a general OP1→OP2 migration mechanism for any OIDC providers (not just Mobile Connect), then the doc would be much better removing all the MC, MNO, and phone number stuff.

TL: I tried, seems I failed :-)

In §2 "Overview" I would describe the first section as an API (instead of a protocol) offered by the old OP that is used by the new OP to obtain information about the account being migrated.

§3 "Migrating a User Account between Ops” explains discovery steps, multiple OAuth steps, and the API call all together. It would be clearer if we could specify the API and say it is OAuth-protected, leaving a full example flow using one example variety of OAuth to an appendix.

TL: thanks. I think we need to restructure the document in the next round.

Pairwise 'sub' values are tied to a sector id (a domain name) — not a redirect_uri or sector_id_uri — so the response items should have a "sector_id", not either a "redirect_uri" or "sector_identifier_uri".
I guess "sector_id" should also be optional to support OPs that use public (non-pairwise) "sub"s.

TL: need to look into this in more detail
@John: could you take a look?

The items returned by the old OP repeat the "sub" and "sector_id…" values: as direct JSON, and also in the "porting_data". That feels like poor design that just introduces the possibility of mismatches leading to security bugs.

TL: I realized that while reviewing the doc the last time, but it was much too late :-) What we need in the end is an array of assertions (which are un-encrypted).

The API response is an array of per-sector-id items. That leaves no room for any future extensions that apply to the whole account. It would probably be better as a top-level object with a "subs" element holding the array.
{
  "subs": [
    {"sub":…, "sector_id":… },
    {"sub":…, "sector_id":… }
  ]
}

The example signed porting data has an 'exp' (expiry) value that is 15 minutes after the issuing (porting) time. That will not work, given that an RP is expected to verify it, say, months in the future.

TL: copy and paste 

The example "porting_data" values are missing 'kid' (key id) values. They are very necessary in this case due to the long lifetime of the signatures (eg signed at porting time; verified by an RP on login perhaps months later).

The example "porting_data" values use symmetric MACs (HMAC), as opposed to asymmetric signatures (eg RSA). I doubt that can work.

TL: You are right. It's all copy and paste as well - It takes some time to make up perfect examples ;-)

The "porting_data" looks like an id_token from the old OP. In fact, it might even be accepted as an id_token by some RPs, which will silently ignore the "migrated_to" element as an unknown element for an id_token. Is that dangerous? I’m not sure; I’m not sure it isn't. We really need an element in the signed data to unambiguously identify the semantics of the message.

TL: good point - any sugesstions?

The old OP knows the new OP (hence the value to put in "migrated_to") based on the client_id of the new OP’s app that is calling the migration API.

TL: you are right. That also means we need a way to setup and maintain trust relationships among MNOs/Ops, something not addressed in OIDC or MC. Either is based on manually set up relationships or dynamic registration.

"porting_data" in the id_token is a single JWT. Probably needs to be an array of JWTs as a user ports from OP1 to OP2 to OP3 (or back to OP1?). It is a bit of a corner case

TL: I would like to stick to the "simple" case OP1 -> OP2

"Host: discovery.example.com" is used in one example [§3 step 4]. I suspect that should be "Host: op.mno1.com", using the value from the "authorization_endpoint" from the previous step. Also change "GET connect…" to "GET /connect…" (add leading /).

The API call gets data for a specific account but uses a generic path "GET /connect/migrate", relying on the access_token to pick the right account. I’m not sure if this is the best way to design an API. The Mobile Connect migration spec adds the phone number in the path. Perhaps it isn't necessary, but it might help ensure each side is talking about the same user.

op1.example.net and op2.example.com might be better sample values than op.mno1.com and op.mno2.com.

I wonder what the best order of steps are for an RP in §4? After failing to find id_token.sub+iss in its DB, the RP might be better to look for id_token.porting_data.sub+iss in its DB before verifying the old OP’s sig, particularly if it involves calls to config and JWK URIs.

TL: could be modified that way. I wanted to make sure first the JWT's integrity.
--
James Manger

-----Original Message-----
From: Openid-specs-mobile-profile [mailto:openid-specs-mobile-profile-bounces at lists.openid.net] On Behalf Of Torsten.Lodderstedt at telekom.de
Sent: Friday, 10 June 2016 9:01 AM
To: openid-specs-mobile-profile at lists.openid.net
Cc: jbradley at mac.com; philippe.clement.ft at gmail.com; jbradley at me.com; vboyalakuntla at gsma.com
Subject: [Openid-specs-mobile-profile] Account Migration - First Draft

Hi all,

please find attached the first draft of the Account Migration protocol. The design intentionally is kept generic so it can be used to migrate user accounts among any supporting OIDC OP.

Please review it and give me feedback.

thanks in advance,
Torsten.

PS: I'm currently having trouble to upload the HTML and xml source to bitbucket. I will upload it as soon as possible.

-----Ursprüngliche Nachricht-----
Von: Torsten Lodderstedt [mailto:torsten at lodderstedt.net]
Gesendet: Sonntag, 5. Juni 2016 13:43
An: John Bradley
Cc: Lodderstedt, Torsten; openid-specs-mobile-profile at lists.openid.net; philippe.clement.ft at gmail.com; John Bradley; jbradley at mac.com
Betreff: Re: [Openid-specs-mobile-profile] MODRNA WG Call June 1st 2016

Am 04.06.2016 um 14:17 schrieb John Bradley:
>
> We can.  I think the GSMA was going to discuss our feedback.
>

I will draft a first version.

> They had some other concerns with people doing multiple ports over a 
> short period of time.  I don't know how much history is wort 
> supporting vs increased complexity for the client
>
The easier approach is to ask the user to force migration at the RP by logging in after every port. Otherwise, this is ending up in signficant increased complexitity and potentially security holes.


More information about the Openid-specs-mobile-profile mailing list