Skip to content

fix(network): accept rootless Zakura header responses#482

Closed
p0mvn wants to merge 1 commit into
ironwood-mainfrom
split/pr458-rootless-response
Closed

fix(network): accept rootless Zakura header responses#482
p0mvn wants to merge 1 commit into
ironwood-mainfrom
split/pr458-rootless-response

Conversation

@p0mvn

@p0mvn p0mvn commented Jul 6, 2026

Copy link
Copy Markdown

Summary

  • Allow solicited Zakura Headers responses without tree-aux roots to decode non-punitively.
  • Add a regression test proving an honest rootless response does not disconnect the peer.

Test plan

  • cargo fmt --all -- --check
  • cargo test -p zebra-network deliver_rootless_solicited_headers_does_not_disconnect_the_peer

Stack

Base PR in the split from #458.

AI disclosure

Used Cursor to split PR #458 into stacked branches and prepare this PR.

Allow solicited header responses without tree-aux roots to reach the reactor non-punitively, so honest peers are not disconnected when they cannot serve optional roots.
@v12-auditor

v12-auditor Bot commented Jul 6, 2026

Copy link
Copy Markdown

Note

Complete: Audit complete. V12 found one issue worth reviewing.

Open the full results here.

FindingSeverityDetails
F-96418 🟠 High
Rootless responses pin range assignments

A peer that receives a native header-sync GetHeaders request can now answer with a non-empty Headers frame whose has_roots marker is false and whose root payload is empty. The changed decoder accepts that solicited frame and the pipe forwards it as a normal WireMessage after consuming the peer-local expected response. The reactor then pops the corresponding outstanding request, rejects the message as malformed because headers.len() != tree_aux_roots.len(), and retries the range without clearing the scheduler assignment for that peer. Misbehavior reporting is record-only, so the peer remains connected and its assignment stays pinned. Three attacker-controlled peer IDs can fill the HEADER_SYNC_FANOUT assignment set for the same range with such rootless responses, leaving the retried range queued but unassignable to any peer until one of those attacker sessions disconnects or the range is covered elsewhere.

Analyzed two files, diff 78d1a5e...7cf2c33.

@p0mvn p0mvn closed this Jul 6, 2026
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