Intercoin / Wallet

It's a secure wallet -- and you don't have to install it!
GNU General Public License v2.0
0 stars 0 forks source link

Solidity: Update to precompiled contract when it becomes available #2

Open EGreg opened 1 year ago

EGreg commented 1 year ago

Keep an eye on this thread, it may lead to a precompiled contract, both to save gas and also make sure that people don't roll their own secp256r1 support in solidity:

https://ethereum-magicians.org/t/eip-7212-precompiled-for-secp256r1-curve-support/14789/4

If news comes out of a new EVM version that has this precompiled contract, and is adopted by most miners, then release a new Account smart contract that uses it, instead.

EGreg commented 1 year ago

We may not actually need to generate the challenge and verify signatures using the blockchain. Thanks to the prf extension to webauthn (which firefox and chrome recently support)! And safari on iOS 17 and onwards supports LargeBlob extension (similar to prf)

As long as the user logs into the website with the same username and gets the same challenge, the authenticator would then return the same PublicKeyCredential.getClientExtensionResults. And this can be used as the material for generating the non-extractable symmetric encryption key, that stays inside the secure HTML+JS environment and is never sent to any server. Please see this for details: https://blog.millerti.me/2023/01/22/encrypting-data-in-the-browser-using-webauthn/

In this way, one can store the actual EVM secp256k1 private keys on a server.

Possible Vulnerabilities

1) Quantum computers may be able to break the cryptography with the information saved at rest on servers

2) Servers may experience a denial-of-service attack, or go offline for other reasons, making it harder for users to recover their keys. Since 2020, iOS Safari deletes all script-writable storage after 7 days, however Apple also provides CloudKit JS API

3) The servers hosting the "secure environment" may be hacked, or the DNS + HTTPS certificate may be compromised, and serve Javascript that is able to steal the secret encryption key. Then, the user may be convinced to load the "secure environment" URL as a top-level document in the browser, or inside an iframe from a colluding website that has a malicious "integrity" attribute. The user would then log in, use the secret encryption key, and thus reveal all the private keys to the malicious JS, which can then send them anywhere.

To mitigate #3, we register a service worker to intercept all requests to the secure domain and serve the trusted payload. However, iOS Safari purges the service worker registrations every 7 days, making the vulnerability possible. It does make an exception for PWAs which are installed on the home screen, however this doesn't prevent a user from loading the "secure URL" inside Safari, since iOS Safari doesn't support link capturing / universal links. Here is more information on how this hurts web-based wallets: https://dmihal.medium.com/apple-just-killed-local-storage-what-that-means-for-burner-wallets-412d49a71485

In short, Safari actively prevents us from guaranteeing that a page at a URL never changes. The best we can do is use the "integrity" attribute on an iframe, but the user may be tricked as described in #3 above. This is why we need the Intercoin Wallet to ultimately be hosted on a browser like Firefox or Chrome (perhaps even in iOS), and have the website scan a QR code from them using the camera, in order to authenticate or authorize a transaction. This is good practice anyway, for larger transactions, or for voting, as the user can double-check that they are signing what they expect, and not being lied to by a compromised interface.

Secure-enough solutions within browser

However, there is a workaround: to sign transactions, we can have the user visit only a website on a server that they trust (not necessarily Intercoin's wallet, but their own website) and which will include the Intercoin Wallet domain in an iframe, in a secure environment. (The server can even do so by pointing a subdomain via CNAME to the Intercoin Wallet domain). In addition, the Intercoin Wallet secure environment will require receiving signed data (with a recent timestamp) to be sent by the relying party (external website including the Wallet iframe) via postMessage into the iframe that loaded the Wallet environment. This secret data from the relying party will be an essential input for the decryption key, and SRI ensures that the page loaded in the iframe will not retain it or save it (even in IndexedDB) and thus this secret data would be missing if the environment was loaded in a top-level browsing context.

In fact, the "secure environment" can be hosted on the user's own trusted server, and the intercoin-wallet.com domain can be an intermediate domain that just proxies messages. Like this:

1) External (top-level) website has iframe with with "integrity" to load: 2) Intercoin-wallet.com has iframe with with "integrity" to load: 3) User's trusted host, loads static secure HTML + JS + CSS web environment

In this case, #2 has the user log in, and then loads the iframe with their trusted host. It proxies messages between 1 and 3, and 1 doesn't know the domain of 3. Thus, users who are concerned about their interface can actually host the secure environment on their own servers. Now, an attacker would have to compromise every user's host, and intercoin-wallet.com, and also convince people to visit a malicious website (relying party) that has the wrong "integrity" attribute.

EGreg commented 1 year ago

Good news: on iOS, inside an iframe, we can have a button to launch the wallet in Google Chrome or Firefox browsers, and the user isn't going to be fooled. However, in that case, we may as well have the user download the Intercoin Wallet as an app, after all. And this app will be able to add a native Safari extension.

The following URI schemes can open a link in Google Chrome for iOS <a href="googlechrome://example.com">try it on Chrome</a>

And this is the URI scheme to open a link in Firefox for iOS firefox://open-url?url=https://www.google.com/search%3Fq%3Dfirefox%2520for%2520ios

However, this means the user would have to download one of these browsers. This is an alternative to having to scan a QR code on Firefox / Chrome / Edge running on a desktop computer, however. For now, we can be sure on these environments that the service worker isn't removed after 7 days, unlike in iOS Safari.