#38671 [BC-Insight] Signer key rotation is not possible due to deadlock between submitting key rotation to Stacks and retrieving it
Submitted on Jan 9th 2025 at 09:32:27 UTC by @n4nika for Attackathon | Stacks
Report ID: #38671
Report Type: Blockchain/DLT
Report severity: Insight
Target: https://github.com/stacks-network/sbtc/tree/immunefi_attackaton_0.9/signer
Impacts:
A bug in the respective layer 0/1/2 network code that results in unintended smart contract behavior with no concrete funds at direct risk
Description
Summary
Rotating a signer's key is currently impossible since signers build their state machine for DKG based on the last signer set they have in their database. This set, however, is only set AFTER a DKG was successful and a corresponding transaction was sent to Stacks. These two actions basically deadlock each other, preventing key rotations overall.
Finding Description
In transaction_signer::handle_wsts_message
, we see the signing set used for DKG is retrieved from the signer's database:
This defaults to the bootstrap signer set from the config if there is no other rotate-keys
transaction in the signer's database. This shows us the first requirement, namely that we need to have a rotate-keys
transaction confirmed on Stacks, containing a NEW signer set.
Now in order to submit such a transaction, the coordinator must get signatures for a ContractCall::RotateKeysV1
contract call, which get validated by the singers:
We see, that a requirement here, is that the new signer set must match the latest signer set we have in our database. Now this signer set is ONLY set after a successful DKG.
Putting these together, we see that we have a logical deadlock making it impossible for a key rotation to happen
Severity
I see this as Insight, since key rotations are technically disabled currently. If they should be usable right now, this would be medium in my opinion since it breaks intended functionality.
Mitigation
In order to properly rotate a key, we need additional functionality for signers to add a temporary "proposed" signer set to their storage. This would then need to be retrieved when a DKG is triggered. This should probably be done manually by each individual signer in order to guarantee a quorum of signers agrees with the change (a new signer set can only be adopted, if a quorum of the old signer set agrees on it).
Note: Do NOT allow the coordinator to specify the new set since this would potentially allow them to take over the system.
Proof of Concept
I was asked to submit this without a PoC by djordon
Was this helpful?