User Privacy Concerns with the new Canister Chosen Alternative Origins feature

My concerns

One of the beautiful parts of Internet Identity is that it prevents applications from tracking users across the IC. It assigns a new principal for each canonical canister frontend URL (https://<canister_id>.ic0.app) that one interacts with. This is great for user privacy, but can be a headache for developers that want to track users across their ecosystem, or users that don’t like logging in more than just once.

The new Canister Chosen Alternate Origins opens the door for a single application to track users across multiple 3rd party applications on the IC.


Here’s what the Canister Chosen Alternate Origins does

The new Canister Chosen Alternate Origins feature works as follows,

Source

A frontend canister can provide a canonical canister frontend URL (https://<canister_id>.ic0.app or https://<canister_id>.raw.ic0.app) as a derivationOrigin, meaning that Internet Identity will issue the same principals to the frontend (which uses a different origin) as it would if it were using one of the canonical URLs.

Additionally, in order for Internet Identity to accept the derivationOrigin the corresponding backend canister must list the frontend origin in the JSON object served on the URL https://<canister_id>.ic0.app/.well-known/ii-alternative-origins (i.e. the canister must implement the http_request query call as specified here).


This means that any canister application that lists another canister application as it’s derivationOrigin will be able to track a single principal across multiple applications.


Developers love this, why is this an issue?

When users see a login screen for the newly proposed Canister Chosen Alternate Origins feature like the example shown below, many users won’t think twice that they are authenticating to a different service than the current canister. There is no warning, and most users don’t have canister-id urls memorized to the point where they associate them with a specific app.

source

image

If we allow users to be tracked across the the IC, we lose the user privacy shield provided by Internet Identity. Every canister application a user logs into gets a unique principal, and therefore users cannot be tracked across the IC without providing that information willingly (i.e. phone number, etc.)

Other auth providers may choose to run on top of Internet Identity to allow a single sign-on type of experience, but now there is no option that guarantees this same level of privacy.

In designing this feature, DFINITY did not anticipate that 3rd party applications could voluntarily or through incentives/coersion set a canister url that they do not own as the derivation origin. Why might they do this?

“Malicious” Scenarios where this might reasonably happen

  1. User tracking for Advertisement
    i. Advertisers or investment firms may see a large application or service on the IC, let’s call it “big social app A” as an avenue for tracking users across the Internet Computer.
    ii. They may see the potential revenue associated with tracking users across the IC, and acquire a significant stake in that application, directing efforts towards the application developing “premium features” (SEO, analytics, visibility of NFTs) that many 3rd party applications would benefit from.
    iii. In return for the “premium features” 3rd party app, “app canister B” would need to do is list <big social app A's canister> as their derivation origin. However, this means now that a user logging into app canister B would unknowingly be logging into big social app A.
    iv. Hopefully app B trusts big social app A, because now when a user logs into big social app A, social app A can now make calls into app B’s backend and query/update that user’s data
  2. Powerful interests/governments
    i. Government of country C has outlawed crypto, or wants to tracks users across the IC for tax reasons
    ii. Big social app A decides to decentralize themselves through the SNS or sell a significant stake to fund future work, and country C is a big buyer, directing efforts towards the application developing “premium features” (SEO, analytics, visibility of NFTs) that many 3rd party applications would benefit from.
    iii. See step 1-iii)
    iv. Now unbeknownst to app B and all of it’s users, the government of country C is tracking all of their user data and can manipulate user information in app B through their logins to big social app A.

Especially in the crypto space, there should be more IC native protections around user privacy and tracking - we can’t always trust big money interests.


How did I miss this?

For those who missed this feature & release (including myself, it all happened super fast):

  • On Monday of this past week (July 11th), a forum post titled Release Announcement: Canister Chosen Alternative Origins was published
  • Just one day after (July 12th) a System Canister Management (non-governance) proposal for it was submitted to the NNS, meaning that because >99.99% of us default follow the DFINITY foundation on this topic it passed instantly, with over 4 million votes for, and only 2,097 votes against.

What’s next?

The Canister Chosen Alternate Origins feature is already live on the IC, and I know of at least one large application that is already using it.

I would love to hear from DFINITY, the II team, and @frederikrothenberger regarding my concerns and to find a potential solution, even if that means rolling back this change (if there is enough push-back from the community).

7 Likes

Tagging several members of the community for visibility and additional insight (Sorry for the spam!)

@lastmjs @dostro @quint @skilesare @Zane @wpb @Sherlocked @borovan @nomeata @jwiegley

1 Like

I like the idea of logging into a dApp with a different principal for every dApp. The only use case where this is a problem so far is when I wanted to start using NFID on DSCVR, but have been using II since genesis. I’d rather have some mechanism for transferring my DSCVR data from one principal to another principal. I’m not sure if this is what CCAO is intended to solve, but it would be nice. Of course, I want to be able to choose this data transfer and I want it to be intuitive. However, if CCAO has a “malicious” scenario as described by @icme then I would want it resolved asap. I would be interested in hearing from DFINITY about this issue to know if they considered it.

2 Likes

I am not sure I see the problem. This feature requires opt-in from the code at both domains (alternative-origin.com and derivation-origin.com), so they are already ~colluting~ working together.

Even without the feature they could have implemented this flow with a bit of JS work (user goes to alternative-origin.com, they get redirected to derivation-origin.com for the purpose of II authentication, and then redirected back). All this feature does is to make it easier what’s already possible. So I would not be alarmed by this change.

Nice Identity Anchor, btw!

7 Likes

Agree with @nomeata.

Ultimately I think developers will understand they’re entrusting the existence of their application with another entity if they chose a derivation origin they don’t control.

The malicious scenarios you provided assume they don’t understand or don’t care… perhaps we add this disclaimer somewhere if it’s not in the docs already? We’ll add it to NFID docs next week.

PS @wpb we’re finishing up the ability for users to use II or NFID to sign in to the same anchor and generate the same principals for each target application - it does not leverage this feature but hopefully will have these docs ready next week, too.

6 Likes
  1. Already a much worse issue with plug unless a user is well informed and knows what they are re doing.

  2. At first I was super jazzed about this because we are working on some features at Origyn involving multi-canister access from the same URL as well as applets that can be served from those canisters. I spoke with @frederikrothenberger and asked some questions. My excitement is somewhat muted because I don’t want to give many apps access to all other apps. There is a “delegation” feature coming the future to allow for user directs cross service access but I think it is >9 months out. We’ve been architecting an on-chain solution that would move identity on chain for automation purposes, and I know that @dostro and team are working on some best practices and privacy preserving ways to do this.

  3. I think that self-regulation will keep this from happening a bit. If you give a domain(A) access to your app(B) and then A gives access to another app(C), then a malicious UI could call both services without the user’s approval. A’s UI could query all of B’s principal gated data and use it to access C’s services. If some of that data is access tokens or secrets then you’ve opened up a massive security hole for yourself. Or maybe if you had a multi-canister database that could index users’ private data for them in a secure way you might have a killer app.(@icme :eyes: Is it a bug… or a feature :face_with_monocle:)

  4. I think you can query this data? We know all the canister ids(I think), so we could create an index? Shame may be the most underrated security control.

2 Likes

Thanks for all of your thoughtful responses. Following up on a few of your points.

In this case you described, at least these redirects make it more transparent to the end user.

If a developer wants to be overly-trusting/careless with their application, or is convinced by big money interests that’s totally up to them.

This post isn’t focused on the developer side though - it’s primarily thinking about the user who’s main concern is not convenience or UX, it’s privacy (the “privacy-first” crypto user persona). That’s one of the main reasons that a significant portion of the community still prefers Internet Identity(II) auth.

If II auth gives away those user protections, then there’s honestly no reason to keep using it in my mind (other auth providers/routes give a much better UX).

At the very least, I think there should some user protections inserted into the II login UI to let the user know that they are not just logging into big social app A, but also app (canister) B, C, and D. It might be as simple as having an :arrow_right: dropdown icon with a number :four: (A,B,C,D) next to it showing the number of origins controlled through this login that the user can click on the :arrow_right:, expanding it into a :arrow_down: showing each of the associated application canister ids/origins. The majority of users will ignore and continue through, but a few (privacy focused/paranoid :sweat_smile:) select users will pay attention to this and how far reaching their login/data goes, providing them with more transparency and choice over what it means to login.

For example, if that number jumps from :four: to :nine: → I’m going to dig and find out what new origins my single login point is logging me into, and why this number of origins has increased :slight_smile:

2 Likes

Hi @icme

Thanks for sharing your concerns. I think there is a misunderstanding on how the feature works (and also what we can do about it).

First, let’s address the concern in scenario 1.:

  1. If app A and app B existed before the feature and you have created your app B account using the domain of app B: In order for A to be able to make call to B, it needs to list the origin of B as a derivationOrigin. So if A wants to be the big data collector / aggregator this does not scale: If there was also app C (which has listed A as an alternativeOrigin), a user on A logged in using the derivationOrigin of B cannot do calls to C. So every mapping of principle spaces requires a separate login process (which makes it fairly obvious that something fishy is going on).
  2. If you started using app B using the origin of A from the beginning (i.e. because A offers a launch pad / application portal of some sort), then this feature is not needed at all. You would simply create your account on service B using the principal of A. And you should probably as yourself, why all the services suddenly are hosted on the same URL. :wink:

Also, the feature is transparent to the user. I did not add a warning because e.g. for dscvr.one this is a very legitimate use-case and nothing the user should be alarmed about. We have to be careful about the warnings we show in order to not train users to ignore them (even more than they already do).

At the very least, I think there should some user protections inserted into the II login UI to let the user know that they are not just logging into big social app A, but also app (canister) B, C, and D.

But this is not what’s happening. There is no way that you can login into more than one principal space at once. And as long as B and C are separate, you are logging in into either A & B or A & C, but not both. To be logged in in both you need two separate authentication flows. And we exactly show the other app that you are being logged in to. So essentially the current UI already implements your suggestion. :slight_smile:

It might be as simple as having an :arrow_right: dropdown icon with a number :four: (A,B,C,D) next to it showing the number of origins controlled through this login that the user can click on the :arrow_right:, expanding it into a :arrow_down: showing each of the associated application canister ids/origins.

This is not feasible because the information is not with the canister A but with the canisters allowing A as a derivationOrigin. And every authentication flow lists at most one derivationOrigin. We would have to scrape the whole IC for listings of A within the alternativeOrigins list, which does not scale.

But given that aggregating logins does not scale (see point 1 above) I don’t think this is necessary.
So to summarize: I don’t think this feature increased the risk of being tracked.

2 Likes

@frederikrothenberger

Thanks for the thorough response, and sorry if I’m understanding pieces incorrectly!

A few follow up questions/statements just to clarify my understanding:

Can you elaborate on what you means by “as long as B and C are separate”?

Also, you’re then saying that when into logging into app A, I can log into only one additional derivation origin at a time - is this correct?

But then wouldn’t “creating your account on service B using the principal of A” allow logins to A to make calls directly to B, or any other service (C, D, …N) that has A listed for this set up (they all use the same principal)?

The confusion for me here, is that in reading this it sounds like a user may know that B & C apps have their origin set up as A, but not know about app N. Also, when the user logs into A, doesn’t this same principal allow the a script on the frontend to make calls with it to B, C, …N?

Why is does it not scale?

@icme

Can you elaborate on what you means by “as long as B and C are separate”?

So we are talking about a scenario mapping together multiple services. The statement “you are logging in into either A & B or A & C, but not both” only holds if B does not set C as a derivationOrigin or vice versa (i.e. they are using different principals). This is what I meant by being separate.

Also, you’re then saying that when into logging into app A, I can log into only one additional derivation origin at a time - is this correct?

The correct statement would be one at a time (it is not additional). But you can chose which one by setting the derivationOrigin.

But then wouldn’t “creating your account on service B using the principal of A” allow logins to A to make calls directly to B, or any other service (C, D, …N) that has A listed for this set up (they all use the same principal)?

Ah, you think of a scenario where one application coerces all the other applications to set derivationOrigin (and not the /.well-known/ii-alternative-origins asset) essentially giving up their own principal space.

Yes, I think this is possible. But it would force existing applications to go through a user migration (otherwise they would lose all user accounts) and give up control over all their users. I.e. the application that you are trusting (whose derivationOrigin you are using) could cut you off from all your users at any moment. Developers (as others have already pointed out) should hopefully realize that giving up control that way is a terrible idea. But we will add a warning to the feature specification shortly, to make this point more clear.

Your proposed solution of listing all other aliases seems to be good and simple way of detecting this if developers were to ignore all warnings and start doing this anyway. I will discuss this with the research team and update this thread accordingly. Thanks for creating this thread and kicking off the discussion!

4 Likes

@icme

Quick update on the status of this issue:

  1. We have now added a warning for developers to the feature specification.

    This feature is intended to allow more flexibility with respect to the origins of a single service. Do not use this feature to allow third party services to use the same principals. Only add origins you fully control to /.well-known/ii-alternative-origins and never set origins you do not control as derivationOrigin!

  2. There is now a limit of 10 allowed alternative origins. If this limit is exceeded, Internet Identity will fail the authentication process. We think, this addresses the issue without having to burden users with additional warnings. The limit of 10 was chosen to not restrict developers using the feature correctly, while taking away the incentives to (try to) centralize a large number of services. For context, DSCVR is currently using 6 alternative origins: {"alternativeOrigins":["https://h5aet-waaaa-aaaab-qaamq-cai.raw.ic0.app","https://dscvr.one", "https://www.dscvr.one", "https://dscvr.dev", "https://hax.dscvr.one", "https://dscvr-frontend-staging.onrender.com"]}

These changes will be included in the next Internet Identity update proposal.

2 Likes

Thanks for taking my concerns into account and adding these warnings and limits for now :pray: