fix(recovery): verify recover_account signature against chain owner history - #307
Merged
Merged
Conversation
…istory The recover-account route verified the transaction signature against the recent_owner_authority public key read from the attacker-supplied op body. This was trivially self-satisfiable: an attacker signs with their own key and puts the corresponding public key into recent_owner_authority. The check proved only that the submitter holds *some* key — meaningless for recover_account. Now fetch the on-chain owner-key change history (get_owner_history) and: 1. Assert the op body's recent_owner_authority key matches a real historical owner key recorded on-chain (attacker cannot forge this). 2. Verify the signature against that validated key. 3. Fail-closed (503) if the owner-history RPC lookup fails. Also fix the misleading comment that claimed the DB check was the 'only application-layer gate' — the signature verification is now a real gate too. Tests: add cases for history-key mismatch (400), empty history (400), and RPC failure (503); update mock to support getOwnerHistory.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes audit V2 finding #2 (High): the
recover-accountroute verified the transaction signature against therecent_owner_authoritypublic key read from the attacker-supplied op body. This was trivially self-satisfiable — an attacker signs with their own key and puts the corresponding public key intorecent_owner_authority. The check proved only that the submitter holds some key, which is meaningless forrecover_account.Changes
src/app/api/broadcast/recover-account/route.ts:SteemService.getOwnerHistory(account_to_recover).previous_owner_authoritypublic keys from the chain.recent_owner_authority.key_auths[0][0]matches one of those real historical keys (attacker cannot forge this).tests/unit/broadcast-recover-account-route.test.ts:getOwnerHistorymock, default returns a history containingVALID_KEY_A.Security impact
The path was not exploitable end-to-end before this fix (the DB gate + on-chain
request_account_recoverystill protect it), but the self-satisfiable signature check provided a false sense of security and the misleading comment could cause reviewers to over-trust it. This fix makes the application-layer signature verification meaningful.Test plan
pnpm type-check— cleanpnpm test— 470 passed (3 new test cases)