Skip to content

fix(rpc): bound async operation queue to prevent memory DoS#465

Open
ouicate wants to merge 1 commit into
zcash:mainfrom
ouicate:fix/unbounded-async-operations-dos
Open

fix(rpc): bound async operation queue to prevent memory DoS#465
ouicate wants to merge 1 commit into
zcash:mainfrom
ouicate:fix/unbounded-async-operations-dos

Conversation

@ouicate

@ouicate ouicate commented Jun 10, 2026

Copy link
Copy Markdown

Summary

  • Confirms and fixes GHSA-3wr9-v982-59fj: WalletRpcImpl::async_ops was an unbounded Vec<AsyncOperation> with no automatic pruning.
  • Prunes finished operations (success, failed, cancelled) before enqueueing new async RPCs.
  • Rejects new async RPCs when 64 in-flight operations are already queued, matching Bitcoin Core's DEFAULT_HTTP_WORKQUEUE used by zcashd's RPC layer.
  • Checks the limit before spawning the background Tokio task, so rejected calls do not leak work.

Vulnerability analysis

An authenticated JSON-RPC caller (HTTP basic auth) could call z_sendmany or z_shieldcoinbase repeatedly without calling z_getoperationresult. Each call appended an AsyncOperation retaining full RPC parameters (ContextInfo.params as JsonValue) until explicitly removed. There was no maximum size, expiration, or background cleanup — enabling linear memory growth until OOM.

WalletRpcImpl stored every async RPC operation in an unbounded Vec with
no automatic pruning. An authenticated caller could exhaust memory by
flooding z_sendmany or z_shieldcoinbase without polling results.

Prune finished operations before enqueueing new ones, reject new async
RPCs when 64 in-flight operations are already queued (matching Bitcoin
Core's DEFAULT_HTTP_WORKQUEUE), and check the limit before spawning the
background task.

Co-Authored-By: Composer <noreply@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant