-
Notifications
You must be signed in to change notification settings - Fork 106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make MetaAddr.last_seen into a private field and fix sanitize security risk #1942
Conversation
`sanitize` could be misused in two ways: * accidentally modifying the addresses in the address book itself * forgetting to sanitize new fields added to `MetaAddr` This change prevents accidental modification by taking `&self`, and explicitly creates a new sanitized `MetaAddr` with all fields listed.
/// Sanitize this `MetaAddr` before sending it to a remote peer. | ||
pub fn sanitize(mut self) -> MetaAddr { | ||
/// Return a sanitized version of this `MetaAddr`, for sending to a remote peer. | ||
pub fn sanitize(&self) -> MetaAddr { | ||
let interval = crate::constants::TIMESTAMP_TRUNCATION_SECONDS; | ||
let ts = self.last_seen.timestamp(); | ||
self.last_seen = Utc.timestamp(ts - ts.rem_euclid(interval), 0); | ||
self.last_connection_state = Default::default(); | ||
self | ||
let ts = self.get_last_seen().timestamp(); | ||
let last_seen = Utc.timestamp(ts - ts.rem_euclid(interval), 0); | ||
MetaAddr { | ||
addr: self.addr, | ||
services: self.services, | ||
last_seen, | ||
// the state isn't sent to the remote peer, but sanitize it anyway | ||
last_connection_state: Default::default(), | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is the security risk fix:
- peers in the address book can't be modified because
sanitize
takes&self
- new fields must be sanitized because
sanitize
constructs a newMetaAddr
, listing every field
services: *services, | ||
last_seen: *last_seen, | ||
// the state is Zebra-specific, it isn't part of the Zcash network protocol | ||
last_connection_state: NeverAttempted, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use explicit NeverAttempted
rather than PeerAddrState::default()
for readability.
This refactor lets us remove `MetaAddr::update_last_seen()`.
Re-running jobs due to a cargo download failure. |
Motivation
In #1849, we want to replace the
MetaAddr.last_seen
field with 3 more specific time fields.This PR prepares for this change by making
last_seen
into a private field.It also modifies the
sanitize
function so it's harder to misuse.Solution
The code in this pull request has:
Security
In 9bcfb44, this PR fixes a security risk when using
sanitize
, where new code could:See my comment for details https://github.com/ZcashFoundation/zebra/pull/1942/files#discussion_r601212080
Review
@oxarbitrage can review this PR. It's urgent because the rest of #1849 depends on it.
This PR is mostly interactive renames and code movement. I've added review comments in the two places that actually change Zebra's behaviour.
Related Issues
First part of #1849
Follow Up Work
Rest of #1849