Asta Li
|Jan 4, 2024
In Part 1 of this series, we described crypto wallets as both bank vaults and metrocards.
“As bank vaults, wallets help users secure their digital assets as well as take simple actions on public systems. Like a bank vault, they should be secure, sturdy, error-proof, and immovable. Like metrocards, they should be lightweight, flexible, intuitive and easy to replace. Across UX and functionality both, metrocards and bank vaults should not be the same.”
Accordingly, we see the web3 applications that embed wallets within their products span a wide range of requirements. While some web3 products require the strictest “bank vault” settings, where all users must KYC and are required to authenticate over multiple factors for every transaction, other web3 products optimize for “metrocard” flexibility: access is as easy as connecting a social account.
Even within the same application, users have different needs. It’s important to recognize that when users engage with a product for the first time, they are often still investigating value and are deterred by onboarding friction. For those newcomers, accessibility is paramount. A wallet system must be strongly secure by default for the broad base of users, with additional security features available to those who need it.
In this post, we break down a basic threat model for thinking through Privy’s embedded wallet system. A major part of our work is to enable secure defaults for developers and work with them to configure the system to their application.
A thoughtful accounting of threat models is essential for selecting the correct point in the product decision space. It is foundational in both designing a secure system and educating developers and users in how it can be used.
At Privy, we seek to provide secure defaults and, from there, configurability across the entire spectrum so developers and users can choose according to their product requirements: understanding and explaining threat models is essential to our work here, as is laying out various threat scenarios.
In this post, we cover a high-level breakdown of how we consider threats. The full range of security analysis is a much more nuanced and extensive topic.
Broadly speaking, we consider the following threat landscape when looking at an embedded wallet system:
Denial of service: This class of attacks cover if services or applications become unavailable, potentially rendering access to a wallet unavailable. For instance, what happens if AWS goes down or an application goes out of business?
Third-party attack in a web environment: This class of attacks covers those that can be run by a third-party external to the user or application: injecting malicious code via bookmarklets and browser extensions, XSS, violating browser guarantees. This covers exploiting insufficiently-protected websites and apps, authentication systems, and cryptosystems, as separate from modifying the underlying application or wallet system in place.
Compromised user: A user is phished or coerced into sharing credentials, passwords, tokens, device access such that an attacker is indistinguishable from the user.
Compromised application: A third party attack on the hosting application code and environment, for instance a supply-chain attack affecting the application code. For simplicity, we treat this similarly as a rogue app developer.
Rogue app developer: This class of attack contemplates a malicious app developer. The developer controls the application within which the wallet is deployed and controls the full context for the wallet as well.
Compromised infrastructure provider: This is a third-party attack on the infrastructure provider, for instance via supply-chain attack or compromise internal to the infrastructure provider. For simplicity we treat this similarly to the rogue infrastructure provider threat.
Rogue infrastructure provider: This threat model encompasses a rogue infrastructure provider attempting to independently compromise user accounts, for instance due to insider threat or other means of compulsion.
We will start off with the simplest UX and most basic threat model and build from here. In all cases, the system is built so the end-user is the only party who can access private keys, within an isolated iframe environment on their device.
Base case: We want a secure wallet system that can withstand a third-party attacker. This assumes the user is not compromised and browser security guarantees hold.
The most accessible user experience that meets the requirement is a simple login using a universally approachable account such as email, Google, Apple, etc. Privy’s email OTP login and social integrations, along with automatic recovery via Privy escrow, can be used to enable access to an embedded wallet in this way. In any setup, developers are also responsible for making sure their applications are secure and educating users against installing untrusted browser bookmarklets and extensions.
At a high level, the architecture is as follows: the user holds a device share, Privy holds an auth share, and Privy’s recovery escrow service holds an encrypted recovery share to enable automatic recovery.
Using Shamir’s Secret Sharing, all keys are split client-side and Privy never stores full private keys. Private keys are only ever reassembled client-side, in an isolated iframe, on user devices.
Due to Privy’s cryptosystem architecture, even if Privy databases were breached and published on the public internet, no wallet private keys can be compromised.
As we explore additional threats, we’ll discuss security features that Privy enables developers to layer onto the default base.
Threat: User login method is lost
What it is: A user loses access to their auth method. This means a given user who can no longer log in to access their wallet
Solution:
Users can select login methods with built-in recovery, such as Google or Apple.
Developers can enable additional recovery methods tied to an account.
Threat: User login method is compromised
What it is: An individual user’s auth method is lost to an attacker. The attacker can log in as a user and gain unauthorized access to the user’s account
Solution:
Authentication MFA, wallet MFA, password-based recovery
Compromised primary login method does not lead to any wallet access when either wallet MFA or password-based recovery are enabled.
Threat: Application goes down
What it is: A Privy customer goes down. Users can no longer access the customer application, and therefore cannot access the wallet embedded within the application.
Solution:
Privy works with customers to host an application-specific recovery service even if the application is no longer available.
Users are able to recover their wallets using their device share and their recovery share.
Threat: Application goes rogue
What it is: A given app becomes malicious or it is compromised through insider threat, takeover, malware, etc. Because the application provides the context for the wallet embedded within the application, features such as UI customization and headless signatures can be used to attack the user.
It’s important to note that in certain cases Privy enables developers to trigger signatures for a user while they are active in an app. This is important for apps where context switching is costly (such as games) but gives the developer a lot of power.
Solution:
Privy works with application developers to provide guidance on securing their products, including reviewing their configuration settings and recommending best practices: enforcing allowed domains, setting up proper CSPs, and more.
Beyond that, Privy relies on defense in depth through features like transaction MFA, recovery passwords, and isolation of wallet credentials from auth credentials.
Http-only cookies running on an isolated domain means attackers cannot compromise an access token via javascript injection.
Users can set recovery passwords to prevent their accounts from being provisioned on new devices without their direct involvement.
Users can configure wallet MFA to require MFA on transactions. In this mode, users are prompted to authenticate additionally via an MFA method such as TOTP, passkeys, or hardware key when they want to perform a wallet action.
Once set, a user’s password and MFA cannot be disabled by the developer.
Beyond this, Privy enables emergency shut offs to prevent the app client from gaining any access to user auth and recovery shares when under attack.
Threat: Privy goes down
What it is: If Privy becomes unavailable, then the wallet infrastructure within applications becomes unavailable to users.
Solution:
Enable cloud/passkey recovery
If Privy becomes unavailable, automatic recovery is no longer possible because Privy operates the recovery escrow service used.
Using a cloud recovery backup or passkey storage for backup of the recovery share ensures that as long as the user has their device and their recovery backup, they will always be able to reassemble their wallet.
Threat: Privy databases are compromised
What it is: If Privy databases are compromised, what are the threats to user wallets?
Solution:
Using Shamir’s Secret Sharing, all keys are split client-side and Privy never stores full private keys. Private keys are only ever reassembled client-side, in an isolated iframe, on user devices.
Due to Privy’s cryptosystem architecture, Privy can recover from a database breach with no compromise to user private keys. An attacker cannot reassemble user keys even with full access to Privy’s database contents.
Key rotation from there enables us to shut out the attacker entirely.
Threat: Privy goes rogue
What it is: Privy itself works to compromise all of its users systematically.
Solution:
Wallet passwords or cloud/passkey recovery provide additional cryptographic recovery security on top of the infrastructure controls Privy always enables by default.
From there, the client environment is entirely on the user’s device and all traffic is inspectable by the user.
Privy does not store passwords. This does mean that if this password is lost and the user does not have their device share, the wallet is fully unrecoverable.
As we have seen, the appropriate configuration for any system depends on your threat models and your product requirements. Just as users are not all of a kind, we know self-custodial systems are not one size fits all and should be easily upgradable by both developers and users.
As part of this, we are continually working with security researchers and auditors to test our systems, identify and mitigate threats. If you’re a security researcher and you’ve found something of interest, please reach out! We’d love to work with you.
At Privy, we believe secure systems can be delightful – and will usher in new user experiences on the web. We’re excited to build a powerful, flexible system that enables seamless user experience, strong protection against threats, and world-class security. If this work is interesting to you, we’d love to chat.