Vulnerability Report: Privacy Issue in WabiSabi Protocol #116
Closed
drkgry
announced in
Announcements
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Vulnerability Report: Privacy Issue in WabiSabi Protocol
Summary
A vulnerability has been identified in the WabiSabi protocol, which serves as the privacy-preserving mechanism for coordinating CoinJoins within the Bitcoin network. This vulnerability allows a malicious coordinator to compromise user privacy. Specifically, it enables the coordinator to identify individual users' coins and link inputs to outputs, thereby undermining the privacy guarantees of the CoinJoin process.
The vulnerability arises from insufficient client-side validation of the credential issuer, which the coordinator can exploit by employing multiple credential issuers. This allows the malicious coordinator to differentiate between input and output registrations, enabling them to trace input ownership and break the anonymity set of the CoinJoin.
Affected Versions
Impact
The vulnerability exposes users to the following risks:
Vulnerability Description
Technical Overview
CoinJoin is a special type of Bitcoin transaction where multiple users combine their inputs and outputs into a single transaction. The WabiSabi protocol coordinates this process, ensuring that the privacy of each participant is preserved. The goal of the protocol is to be completely trustless, meaning that even a malicious coordinator cannot extract any information to link users or identify their coins. This is achieved through the use of cryptographic methods, the Tor network, and client-side checks.
In each CoinJoin round, users register the coins they want to include (UTXOs), specify their outputs, and provide signatures by using the WabiSabi protocol. The coordinator then constuct a single Bitcoin transaction that is broadcast to the network. A critical feature of the protocol is the use of anonymous credentials, which ensure that users receive back exactly what they registered without the coordinator being able to link inputs to outputs.
The vulnerability we discovered affects the protocol's credential system. In each round, a credential issuer is responsible for providing users with anonymous credentials. These credentials function like tokens, allowing users to privately participate without revealing ownership of their coins.
However, we found that the coordinator can exploit a lack of validation in the client-side checks by issuing multiple types of credentials during the same round.
To illustrate with an analogy: imagine the coordinator is like a bank in a board game. When you bring your coin (UTXO) during input registration, the bank issues you "monopoly money" (tokens), that you can later use to buy outputs. Since you’re wearing a mask that can change at any time, the bank doesn’t know who you are, only that the value matches. However, with this vulnerability, the bank can give different types of tokens (Monopoly money, Hotels money, The Game of Life money, etc.) to different users, allowing it to track who is spending what. By doing so, the coordinator can distinguish between input and output registrations, compromising the privacy guarantees and deanonymizing participants.
The CoinJoin round begins when the coordinator creates a round, and participating clients detect this and start polling the round’s status. The status is updated with a series of round events as the process progresses. For instance, the first event is "RoundCreated" contains key parameters such as "maxAmountCredentialValue," which defines the upper limit for the credentials that will be issued during the round.
To minimize network traffic, clients only request new events from the coordinator each time, appending them to their own internal list. This method allows clients to track the round's current status incrementally, without needing to request previously received events. As a result, clients never verify the consistency of past events.
This has two important consequences. First, the coordinator can send different "RoundCreated" events to each client without being detected, as clients do not cross-check previously received events. Second, the creation of both the
WabiSabiClient
and theCredentialIssuer
—which handle the generation and verification of anonymous credentials—is dependent on two parameters, one of which is included in the "RoundCreated" event. This causes the client to use the same credential throughout the entire CoinJoin process. Consequently, the coordinator can link every request made by a user during the process (e.g., input registration and output registration), revealing that they originate from the same participant.Additionally, since the round status is shared across the entire client application, this vulnerability affects all wallets within the client. This means that coins from multiple wallets are implicated, allowing the coordinator to correlate inputs and outputs across different wallets, further compromising user privacy.
Steps to Reproduce
Condition for Exploitation
No special conditions are required beyond the client utilizing the CoinJoin service.
Actions Taken by the Attacker (Malicious Coordinator)
maxAmountCredentialValue
in powers of 2, ranging from 2^2 to 2^36 BTC. This creates 34 distinct groups. A similar approach can be applied with themaxVsizeCredentialValue
to double the number of groups.maxAmountCredentialValue
the client’s request matches. If it’s the first time that this particular issuer has been used, it is removed from the rotation list.Result of the Exploitation
The coordinator can track each user through the CoinJoin process by linking their inputs and outputs via the credential issuer, effectively deanonymizing the transaction. Additionally, since the round status is shared across all wallets in the client application, the coordinator can link inputs and outputs across different wallets, resulting in wallet clustering and a significant compromise of user privacy.
Exploitability
This vulnerability can be exploited by any malicious coordinator with full control over the CoinJoin round. Since the coordinator has the authority to set parameters like
maxAmountCredentialValue
andmaxVsizeCredentialValue
, they can easily manipulate these values during the round-state polling without detection.The exploit does not require any special privileges or external tools beyond what is already available to the coordinator, making it straightforward to execute. As long as the malicious coordinator can control the credential issuers and the event rotation, they can link inputs and outputs, compromising the privacy of all participants in the CoinJoin process.
Given that this attack can be carried out without raising suspicion and the lack of client-side checks on previously issued events, the vulnerability is highly exploitable by any party running the coordination services.
Mitigation
We believe that this vulnerability is not actively being exploited. Based on tests conducted on three of the most popular coordinators, the round state responses were consistent in all cases – GingerPrivacy team.
To mitigate the issue, we recommend the following steps:
Proposed Solution
Polling Event History: Modify the client to occasionally request the full history of round events, rather than exclusively polling for new events. This change would allow clients to verify the consistency of round data across all participants and detect if the coordinator has issued different events to different clients, preventing manipulation.
Use Constant Parameters: Consider adjusting the range-proof width to a constant parameter, ensuring that the same value is used throughout the CoinJoin process. This would mitigate the ability of the coordinator to rotate credential values. Care must be taken to maintain client-server interoperability while implementing this change.
Verify Round ID hash: In the Wasabi coordinator, the round ID is generated based on the round parameters, but this is not cross-checked on the client side. Verifying on the client side whether the same round ID is generated from the parameters resolves the issue.
Beta Was this translation helpful? Give feedback.
All reactions