Umbra Frontend Bug Disclosure User Action Recommended

December 16, 2021 / Ben DiFrancesco

This post is a disclosure of a now-patched bug found in the Umbra frontend. The bug could have resulted in Umbra being configured incorrectly for users in rare circumstances. As a result, these users would not see funds on "Receive" page that were sent to their account.

Note that no user funds are lost or at risk, however in certain circumstances fund recovery could become cumbersome. Users who may have experienced this bug are still at risk of receiving payments that are difficult to withdrawal.

Existing Umbra users should follow the steps below to make sure their account is configured properly as soon as possible.

This will avoid having funds sent to them via Umbra that will require a support request to withdraw.

TL;DR What should I do?

Any user who configures Umbra moving forward is unaffected, as is any user who configured their Umbra account after December 16th, 6:00 PM UTC.

Any user who configured Umbra and already successfully received and withdrew at least one stealth payment can also be sure they are not impacted.

Any user who configured Umbra before December 16th, 6:00 PM UTC, but has not yet received a payment via Umbra, should take the following simple steps to ensure they were not impacted by this bug:

  1. Navigate to https://app.umbra.cash/receive
  2. Connect your wallet and sign the message
  3. If you see a green checkmark below the table, and no warning message, you can be confident your account is configured correctly.
  4. If you do see a warning message, click the provided link to repeat account setup and fix your account

So what happened?

  • A user reported that while experimenting with Umbra, funds sent to an account they controlled did not appear on the Receive page
  • While investigating, we ruled out the most obvious sources of user error that have resulted in these reports in the past, such as being connected with the wrong account or to the wrong network.
  • Once we realized a bug might exist, out of an abundance of caution, we deployed an update to the Umbra frontend disabling the sending of funds. We deployed this update on December 16th, 2:49 PM UTC.
  • While further investigating this report, we discovered a bug in the setup flow that— in a very unlikely set of circumstances— could have resulted in the wrong keys being published to the Umbra stealth key registry. We learned this bug:
    • Requires a very particular and unlikely set of circumstances to occur
    • Would not result in the loss of user funds, though it would make them tricky to withdrawal (impacted users would likely need our support to recover them)
  • We patched the bug in the setup flow, tested our fix internally, and deployed it on December 16th, 6:00 PM UTC. We have left sending disabled for the time being, but will re-enable it soon.

The Technical Nitty Gritty

Background

Umbra generates two public/private keypairs that are used to send and receive funds. These are called the spending and viewing keypairs, and they are generated by the user by signing a message with their Ethereum wallet.

Generating the private keys by having the user sign a special message ensures only the owner of the wallet can create them and avoids requiring the user backup a new set of keys just for Umbra. As long as the user has their wallet's private key, they can generate their Umbra private keys by signing a message.

After the user generates these keypairs, they publish the public keys on chain using the Umbra stealth key registry contract. Senders use this contract to look up the public keys for the account they're sending to and use them to generate a unique stealth address only the receiver can access.

One last detail about these keys: they're unique on a per network basis, because the message the user signs includes the chain identifier of the network being used. This prevents replay attacks if the same account is used across different networks.

The Bug

When an Umbra user with a connected wallet changes the connected account, or the network they're connected to, we reset all relevant state variables stored in the frontend which pertain to this account. This includes the aforementioned public/private keypairs.

However, because we placed this state reset after several network calls, it was possible for the wrong keys to be held in memory if and only if one of these network calls failed. If this happened while the user was going through the setup flow, the wrong keys could be published to the stealth key registry.

Here's an example of what would need to happen for this bug to occur:

  1. The user navigates to https://app.umbra.cash/setup
  2. The user connects their wallet and signs the message to generate the connected account's keys for the current network
  3. The user rejects the prompt to send the setup transaction and publish their keys
  4. The user switches the wallet account they're using, or the network they're connected to
  5. An RPC call to the network fails, showing the user an error toast, and preventing the app from properly clearing the old keys from memory
  6. The user clicks "Submit" to continue the setup process and publishes the wrong keys to the registry
  7. Later, someone sends to the account the user configured, using the wrong keys which have been published to the registry
  8. The user navigates to the receive page, signs the message to generate the correct keys for this account, and uses those keys to scan for funds. None are found.

Resolution

To recover the funds sent in step 7, the user has to determine which account/network were used to generate the keys that actually got published, and use those to scan and withdrawal their funds.

To fix their account configuration, users need to go through the setup process again and publish the correct keys.

To prevent this error from recurring in the future, we moved state reset before any other actions in our code.

To allow users to check if their account setup was impacted, and to ensure this kind of bug does not occur in the future, we added a check to the receive page which validates your published stealth keys match those generated.

Once users have had a 48 hours to validate their accounts are properly configured, we will re-enable sending in the frontend. Note that even if an impacted user fails to update their configuration, their funds will still be recoverable.

Conclusion

Security and safety are our top priority at ScopeLift. We do not take lightly the responsibility of creating software that users trust with their money. For that reason, we felt it important to be completely transparent about this bug, despite the fact that it is relatively minor.

To review:

  • This was a frontend bug and not related to the core protocol
  • No user funds were at risk of being lost
  • One user of thousands is known to have been impacted
  • The bug was patched within a few hours of being discovered
  • Existing users should follow the steps above to be sure their account setup process was not impacted

We are grateful to the ecosystem for supporting our work to bring privacy preserving stealth payments to Ethereum. As a community funded project, we remain committed to a high level of openness and transparency about Umbra, most especially about security and the safety of user funds. Thanks you for your continued support!