Improvements to the Wallet Connect implementation for dApps on Hedera - #1190
Conversation
Signed-off-by: mgarbs <michael.garber@hashgraph.com>
Signed-off-by: Michael Garber <michael.garber@swirldslabs.com>
tmctl
left a comment
There was a problem hiding this comment.
I think this is a great addition and offers a non-breaking feature addition.
Currently to access multi-sig functionality of the network utilizing wallets connected through WalletConnect, a dApp would need to send multiple transactions to be signed to a wallet, resulting in a user needing to accept and sign multiple transactions of the same intent.
The main reason multiple transactions currently would need to be sent by a dApp and approved in an end user's trusted wallet is because a valid signed transaction needs to have a valid node assigned to it. I.E. a transaction sent to a node that it was not intended for will fail by design. When doing multi-sig, there's an increase priority to sign a transaction for multiple nodes. For example, a transaction could have a valid start time of 2 days from now, giving human users the opportunity to gather multiple signatures required for a multi-sig scenario over a couple of days. If a single, multi-signed transaction happens to be for a node that is no longer available during the valid transaction window (2 or 3 minutes), the transaction will not be able to be successfully sent to the network, despite the intent of the group.
The best practice in a multi-sig scenario is to reduce this risk of not being able to submit a transaction to the network at a specified time period by allowing a transaction's body to be sent to multiple nodes. The unique identifier of a transaction is the valid start timestamp in nanoseconds and the payer account id. So a transaction that only differs in node account id cannot be processes twice.
There is a security consideration of sending a list of valid transactions to a wallet and an end user to sign only once. In a naive approach, a malicious dApp could send a disguised list of transactions to a wallet that are not the same. For example, a payload could be sent to a wallet with two transactions encapsulated in a Transaction object. The first transaction could be a transfer of 1 HBAR to a valid account, and the second transaction could be assigning a delelgated spend of 1 million HBAR to a malicious account. In a naive implementation, the wallet would prompt the user to sign both transactions as 1 and the malicious dapp would submit the malicious transaction.
For this method, it is therefore a trusted wallet's duty, burden, and responsibility to verify the transaction bodies are identical in intent before allowing a user to sign. This fortunately is handled by the @hashgraph/sdk javascript SDK.
To strengthen security assurances, while providing the desired functionality and user experience proposed by this HIP, I propose we add a test in this repository or the sdk respository to verify any given SDK version throws an unrecoverable error when trying to deserialize a transaction object in which the transaction bodies do not match.
There was an assumption that the SDK does check on the transaction bodies for an exact match (except node account id) which would be necessarily different for each when a serialized Transaction is de-serialized. This doesn't appear to be the case however, and the SDK team will investigate introducing such a check. Note that the current SDK doesn't allow manipulation of transaction lists, it would take a rogue SDK to enable this capability. |
After checking with the JS SDK team, such a check is in fact in place, see here: |
I just need to raise my hand here and point out that this conversation itself should be noted as a red flag on the design. "Assumption" in how the SDK behaves. I've raised my objections to this design artifact of the SDKs from the beginning. A few small accidental changes in SDK internals could result in an exploit that could be overlooked for a number of versions. I am now at peace because I've said my piece (again). |
@bugbytesinc Thanks and appreciate your concern, note that the assumption has been replaced with a verification that the check is in place in the SDK. An alternative might be for the SDK to accept a serialized transaction for a singular node (or no node at all) and construct a list of transactions for random nodes, sign and return the signatures. It may be then, that we can either:
Choosing 1 or 2 could remove the need for the new method proposed in this HIP altogether. Note that |
Yes indeed. I objected to that back then for the same reasons as well, but "didn't have the votes" as you might say. |
The application layer is free to choose not to leverage TransactionList and enforce a single item in the list, the drawbacks are that the application layer needs to handle potentially more frequent node accessibility failures and ask the user to re-sign transactions. Here's a proposal in code which alleviates your concern which we could implement either in this new proposed method, or ( being mindful of backwards compatibility) as an alternative flow for the existing methods Application Wallet getRandomNodes is a function I wrote, we could have that added to the SDK for convenience and make it a method on the transaction (e.g. .setRandomNodes(numberOfNodes)) Would this approach satisfy your concerns over TransactionList ? |
|
@gregscullard What is the path forward on this HIP? Move forward? Stale? Withdrawn? |
|
@Reccetech Move forwards, definitely not stale or withdrawn |
|
@gregscullard Great. Let us know when your ready to move it into review for better visibility to the community to gather additional feedback. |
Signed-off-by: Michael Garber <michael.garber@hashgraph.com>
|
@bugbytesinc does @gregscullard explanation satisfy the concerns you were having ? I have marked this hip as last call. After this it will go into active state if we do not hear from you. |
Returning a |
|
@bugbytesinc thanks for your comments, I think this could work. |
Changed the return value from signedTransaction and publicKey to signatureMap containing a list of protobuf SignatureMap messages. This prevents potential security issues where returning full Transaction objects with SignedTransaction could enable man-in-the-middle attacks or lazy implementations that don't verify body bytes match the original request. Signed-off-by: Michael Garber <michael.garber@hashgraph.com>
Update hedera_signTransactions specification to explicitly state that only signature maps are returned, not full signed transactions. This prevents lazy implementations that might re-hydrate returned bytes without verification, which could enable man-in-the-middle attacks. Changes: - Clarified Returns section to emphasize signature maps only - Added security note explaining the rationale - Enhanced example code to show proper verification pattern - Added Transaction Body Integrity section to Security Implications Addresses feedback from bugbytesinc regarding transaction body integrity. Signed-off-by: Michael Garber <michael.garber@hashgraph.com>
Security Feedback AddressedUpdated the specification to address @bugbytesinc's security concerns regarding transaction body integrity. Changes Made:
This design ensures that dApp implementations must perform proper verification and cannot blindly trust returned bytes, preventing potential exploits where transaction body bytes might be modified in transit. |
|
@bugbytesinc please review this commit e9484f9 |
|
LGTM |
Signed-off-by: Greg Scullard <greg@hashgraph.com>
|
Minor update to the contents which was missing text relating to the return value in the description for |
Signed-off-by: Michael Garber <michael.garber@hashgraph.com>
Signed-off-by: Michael Garber <michael.garber@hashgraph.com>
|
+1 lets goooo |
…hiero-ledger#1190) Signed-off-by: mgarbs <michael.garber@hashgraph.com> Signed-off-by: Michael Garber <michael.garber@swirldslabs.com> Signed-off-by: Michael Garber <michael.garber@hashgraph.com> Signed-off-by: Greg Scullard <greg@hashgraph.com> Co-authored-by: Greg Scullard <9549788+gregscullard@users.noreply.github.com> Co-authored-by: Greg Scullard <greg@hashgraph.com>
Description:
Updates the header to match new format
Updates the technical section to match the proposed implementation
Adds text to the reference implementation