Description
openedon Mar 9, 2021
Motivation
Zebra accepts and uses far-future untrusted_last_seen_time
s in peer address requests, and passes those times on to other peers.
This is a denial of service or eclipse attack risk, because a single malicious remote node can determine the next 1000 addresses attempted by a Zebra node. It might also let malicious nodes use Zebra to attack other vulnerable nodes. (Zebra tries addresses with the latest untrusted_last_seen_time
s first.)
This bug can also happen with correctly functioning peers, if they have a clock skewed an hour or two in the future.
Zebra's handshake timeout is 4 seconds, and its handshake concurrency limit is 50, so that's 1000 / 50 * 4 = 80
seconds of delayed handshakes for each full list of addresses.
This issue is mitigated by:
- the existing Zebra implementation, which ignores gossiped peers unless it specifically requested them
- Zebra should limit the number of addresses it uses from a single Addrs response, to avoid address book takeover #1869 Zebra should limit the number of addresses it uses from a single node
Solution
Zebra should ignore future untrusted_last_seen_time
s, or adjust them so they are less than or equal to the current time.
Zebra should adjust times from remote peers using the following algorithm:
- find the latest time among all addresses sent by the peer
- calculate the delta from the current time
- apply that delta to each time sent by the peer
This algorithm adjusts far-future times so they don't cause starvation. It also compensates for clock skew, so that different local and remote clocks don't cause other peer handling bugs.
The Version
timestamp field should not be modified, so it can used to detect clock skew.
Alternatives
This is a critical security issue, so we must do something.
We could ignore future times instead, but that causes issues if the local or remote clock is skewed.
We could clamp received times to the nearest 30 minutes, but that removes some useful information, adds complexity, and its overall benefit is unclear. (We already clamp times that we send to other peers, as part of our sanitation.)
Context
zcashd
does not have this issue.
Follow Up
Low-Priority Correctness Change
- make future peer-provided last_seen times into a parse error, if possible, so API users have to handle them
This change should be made in a separate ticket and pull request. It is a low priority.