Protected Recovery Phrases: Plan and Progress

I’d love it if people could share links to PRs in this thread.

1 Like

Maybe the owner can use their names as answers to security questions :laughing: I personally prefer some passwords and a few more security layers added to it.

You created an Internet Identity anchor and used it to log in to the NNS dapp, where you staked 10,000 ICPs in neurons for 8 years. A few months later, an attacker steals one of the devices you use to authenticate.

One very likely “device” to be stolen is IMHO a non-physical device, and that would in our case be the “recovery phrase”. Is there anything we can do to prevent this theft?

Maybe we can require entering multiple authentication and/or recovery devices in order to remove the “recovery phrase”? The actual required mix of the devices would be open for discussion, of course.

1 Like

Threshol sig the recovery phrase. The point is to divide the recover phrase into n tokens out of which any m tokens are required to recreate the recovery phrase. (m < n). See here ( GitHub - icdev2dev/bachao: Social Recovery of Internet Identity) for the concept & MVP.

I like that, I guess we’ll let @lastmjs experiment a bit and he can share some thoughts with us

Yes, but I realize now it would be a bit confusing

Agreed; I’m sure @Oleksii will come up with a nice solution, if there’s anything unclear we can discuss it on the PR once it’s submitted!

Agreed, there are many possible solutions we could implement; I suggest you contribute the idea in e.g. the original thread, and that we keep this thread for discussing the particular solution of “protected” recovery phrases!

1 Like

Alright, it’s been a week!

Quick update from our side:

  • As mentioned here, II now officially accepts external contributions.
  • We’ve gotten started on the “downgrade” test framework, which will be implemented in Rust (as opposed to the existing canister tests that are written in Haskell).

Note that we’ve also pushed some changes to the FAQ to clarify a few things regarding recovery phrases (as they are now), let me know if you have any feedback!

3 Likes

Hello guys. Sorry for delay. My vacation was a bit longer than planned. Guys I’m fan of generic solutions which can be used somehow in future. So I want to propose something like this:



@nmattia @lastmjs @paulyoung what do you think?

1 Like

Hope it was a good one :slight_smile:

I think we should also be careful not to make things more complicated than they need to be; I’ve often found that codebases rarely takes the direction you thought they’d take. In this case in particular I think we’re aiming for a small fix while we hash out the details for a “perfect” solution (lots of great ideas being floated in the original thread).

Did you try the two originally proposed solutions? Were there any issues?

1 Like

@nmattia can you please point me to this solutions? I remember we discussed that we need to use optional field instead of SeedPhraseProtected proposal but without details. Maybe I missed something?

There you go! AFAIR we discussed having either an optional yes/no (see also @paulyoung 's good point here) or an extra variant for KeyType if the first solution doesn’t work.

2 Likes

Got it. Thanks @nmattia .

1 Like

Team,

Let’s start with an alignment:

  • The problem is that an attacker can add or remove any and all devices from a compromised anchor
  • @dostro, @Litzi, and myself from the Internet Identity Labs team and @lastmjs from the Demergent Labs team collaborated on solutions and decided to propose we start with a fix for the most phishable attack vector, the recovery phrase
  • The reason we chose to start specifically with the recovery phrase is because we believe this is the most harmful attack surface, given that it’s the most phishable, and that incremental iteration will generally help make faster and more informed decisions for future improvements

The worst case scenario for a compromised anchor is that the final recovery method, typically the recovery phrase, is removed by an attacker, leaving no opportunity for the anchor owner to recover.

Therefore we propose 3 branches for your review, each implementing a different approach to support a method of protecting the recovery phrase from removal by anyone that doesn’t know it:

  1. GitHub PR to Add new KeyType
  2. GitHub PR for an Optional ProtectionType in DeviceData type
  3. (Our recommendation) GitHub PR for Optional list of Tags in DeviceData type

The flow for each is generally the same:

  • In the remove method, read information about the device being removed
  • If the device is a protected recovery phrase, make sure the recovery phrase the user submitted matches
  • Trap if no match and return without removing the recovery phrase

One important note: Fixing this attack vector still leaves one open that an attacker could add a protected recovery phrase from a different compromised device, even if the anchor already has a protected recovery phrase. We could restrict only 1 protected recovery phrase per anchor in this fix if you all think we should.

1. Add new KeyType

The KeyType enum currently has the following 4 options:

  1. Unknown
  2. Platform
  3. CrossPlatform
  4. SeedPhrase

We propose in this option to add a 5th option for SeedPhraseProtected to differentiate between protected and unprotected recovery phrases.

Strengths

  • A clean implementation with minimal complexity
  • Minimal memory management overhead

Weaknesses

  • This does add another KeyType that needs management down the line, should KeyType undergo a migration (though we’re not aware of any such plans)

Opportunities

  • None besides the immediate feature implementation

Threats

  • None that we’ve identified

2. Optional ProtectionType in DeviceData type

@paulyoung suggested adding a new enum that we implemented as an optional variable to the DeviceData type that could store information about this key being a protected recovery phrase.

Strengths

  • Simple rollback

Weaknesses

  • The DeviceData type will include an additional optional field, which increases state by more than necessary given that only a fraction of devices will need it

Opportunities

  • Possibility to add additional ProtectionTypes in the future

Threats

  • None that we’ve identified

3. (Our recommendation) Optional list of Tags in DeviceData type

Iterating on the 2nd option, the field we add to DeviceData could be a list of Tags as metadata for the device. Not only could it be used to protect the recovery phrase, but it could be used to protect any device, set different administrative permissions per device, and generally add substantial flexibility

Strengths

  • Simple rollback
  • Generalized, reusable solution to make devices more flexible

Weaknesses

  • Such a generalized solution might influence future feature implementations to leverage this rather than a potentially more appropriate, scaleable, harder-to-implement solution

Opportunities

  • As @frederikrothenberger reminded us about @timo’s previous suggestion, this is one way to set different administrative permissions per device so that only devices with the Admin Tag, for example, are able to add/remove devices, Superadmin to add/remove recovery phrases, TxApprover for devices capable of approving transactions, etc, etc

Threats

  • Currently, we’re scoping the reading of the Protected Tag only on removal of a seed phrase because attackers might be able to add their own protected devices, and until there’s a UI for administrative control, we should be more cautious with this feature.

The threat for option 3 requires a more thoughtful approach to the UI in the medium term so that users can configure which devices can add other high-permission devices, but unless Dfinity has medium-term plans to extend device functionality in these ways we believe this enables a highly flexible design space for future feature implementations at low cost.

6 Likes

I’m a big fan of option 3.

I was recently thinking of how cool it would be to share my II with someone, but I wouldn’t want them to be able to approve transactions. This functionality would be amazing

2 Likes

This seems important to do, otherwise an attacker can add a protected recovery phrase that can never be removed by the owner.

That could still happen to people whose devices are compromised who have not yet created a recovery phrase, but if there’s a limit of 1 then at least everyone could proactively prevent this by creating one before a potential attacker does.

3 Likes

I would also vote for introducing this patch

Thanks a lot @Oleksii !

I also think that generic solutions are best, however in this case I fear it may be a bit premature. Right now we don’t know what extra features we’ll add so I’d rather have something simple that can’t be misused, and adapt as we go. Also on the topic of new features:

This would be great, but really we shouldn’t confuse planning for new features and their actual implementation; I don’t think option 1 or 2 would prevent us from adding cool features in any way!

I think @paulyoung makes a really good point that an attacker could use dfx to add another protected recovery phrase!


So, how do we go forward? The II team is really in favor of option 2 to keep things simple and maintainable, would you be ok with revisiting the tags option in the future if necessary?

1 Like

Team,

We’ve moved forward with option 2 above. @lastmjs, @Oleksii, and I want to share the last decision with what we’ll be submitting shortly:

There is currently no concept of “updating” a device in Internet Identity, meaning any sort of logic that turns a Recovery Phrase into a Protected Recovery Phrase would need to be written.

Given that this seems like a substantial change and likely to affect memory management, we will submit a flow that excludes logic for “updating” devices and restrict the submission exclusively to “adding” or “removing” devices.

Unless @frederikrothenberger or @nmattia feel otherwise, this means we have two implementation options:

  1. When the user wants to “lock” (protect) or “unlock” (remove protection) their existing recovery phrase, we query for that public key, remove it, and add it back either as protected or unprotected (whichever the user chose)
  2. Rely on users making a protected/unprotected selection at the point of generating their recovery phrase

We’ve chosen option 2 because option 1 can’t be done atomically, meaning we can’t guarantee that these actions in sequence would succeed even with a retry policy.

Jordan mocked this screen together to show the frontend change

Hi @dostro, thanks for the update!

I’m a bit curious, didn’t we say we’d add a canister method to update the phrase atomically? I really don’t think there’s any significant risk related to having a method that updates the memory to add/remove the protected flag atomically.


Very nice! I guess we’ll need to clarify the difference between “Seed phrase” and “Protected …” a bit though, right now the user has no reason to click on the first one.

Hello everyone!

Apologies for the silence, June has been a little crazy. I took over from Jordan and Oleskii last week but really struggled to find the time to make progress.

That being said, it’s almost ready! I’ve deployed a demo version, you ahead and try it out (don’t use your identity.ic0.app anchors, this is a test deploy): http://fgte5-ciaaa-aaaad-aaatq-cai.ic0.app

This deviates slightly from the original plan, in particular:

  • We don’t offer to create a protected phrase, ever. We just allow making an existing phrase protected. The reason is that it’s really hard to explain what a protected phrase is to someone who doesn’t even have a recovery phrase yet. We’ll do another iteration with our UX guy and improve and clarify the recovery creation process, most likely with a full blown wizard.
  • There’s a new page for handling a device or recovery phrase (including removal), instead of another button on the anchor management page:


That aside, it’s mostly what we all discussed above.

@frederikrothenberger will prepare a release soon and will update you once everything is live; I’ll be away enjoying a cocktail on a sunny beach but with you in spirits to celebrate.

Have a great summer!

4 Likes