fix(api): bound and truncate sign api signatures#6820
Open
Federico2014 wants to merge 2 commits into
Open
Conversation
3for
reviewed
Jun 4, 2026
3for
reviewed
Jun 4, 2026
3for
reviewed
Jun 4, 2026
b13b51a to
dfe3346
Compare
dfe3346 to
95599ad
Compare
95599ad to
a9bdbae
Compare
|
Approved |
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.
What does this PR do?
Hardens the two read-only signature APIs —
getTransactionApprovedList(/wallet/getapprovedlist) andgetTransactionSignWeight— against CPU exhaustion and oversized-signature echo-back.1. Bound the recovery loop (CPU DoS)
Wallet.getTransactionApprovedListpreviously ran a hand-rolled unboundedecrecoverloop. Replaced by delegation toTransactionCapsule.checkWeight, matchinggetTransactionSignWeight.checkWeightrejects up front whensigs.size() > permission.getKeysCount(), before any signature recovery.2. Reject excessive signature counts at entry
Both APIs now check
trx.getSignatureCount() > getTotalSignNum()as the very first step, returningOTHER_ERROR/ "too many signatures" immediately. This is a zero-cost guard that mirrors the bound already enforced by the consensus signature-verification path.3. Truncate oversized signatures at entry
TransactionCapsule.truncateSignatures(trx)truncates any signature > 65 bytes to its first 65 bytes. Called at the top of both methods, beforecheckWeight. The echoed-back transaction is also set on the response builder at entry, so error paths return the truncated form too — no path leaks untruncated signatures.4. Harden checkWeight error message
weight == 0path previously hex-encodedsig.toByteArray()(potentially oversized) into the exception message. Changed to the transaction hash (hash), a fixed 32-byte value that is more useful for debugging and cannot bloat error responses. This protects all callers ofcheckWeight, including consensus paths.Why are these changes required?
getTransactionApprovedListwas the only signature-recovery path without a bound on signature count. A single unauthenticated request with thousands of padded signatures could trigger unboundedecrecovercalls. Signature truncation and the error-message fix ensure clean, bounded, canonical responses on every code path.This PR has been tested by
testApprovedListSigBound— signature withinkeysCountsucceeds; exceedingkeysCountrejected before recoverytestApprovedListSigTruncate— 70-byte signature truncated to 65 bytes, signer still recoveredtestApprovedListTooManySigs— exceedinggetTotalSignNum()rejected at entry with "too many signatures"testSignWeightSigTruncate— same truncation test forgetTransactionSignWeighttestSignWeightTooManySigs— same total-sign-num guard test forgetTransactionSignWeightWalletTest,TransactionUtilTest,RpcApiServicesTest— all green:framework:checkstyleMain,:framework:checkstyleTest— cleanFollow up
None.
Extra details
getTransactionApprovedListnow delegates tocheckWeight, applying the same permission semantics asgetTransactionSignWeight. Behavioral changes:permission.getKeysCount().Callers that relied on the old "recover any signature" behavior to probe arbitrary signer addresses will see stricter results. No database, consensus, or config changes; read-only API paths only.