Skip to content
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

Merged
merged 4 commits into from
Mar 25, 2021

Conversation

teor2345
Copy link
Contributor

@teor2345 teor2345 commented Mar 25, 2021

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

  • Make MetaAddr.last_seen into a private field b9cf9ac
  • Rewrite MetaAddr::sanitize so it's harder to misuse 9bcfb44

The code in this pull request has:

  • Documentation Comments
  • Existing Unit Tests, Property Tests, and Sync Tests

Security

In 9bcfb44, this PR fixes a security risk when using sanitize, where new code could:

  • forget to sanitize new fields, or
  • modify the peers in the address book.

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

`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.
@teor2345 teor2345 added C-bug Category: This is a bug A-rust Area: Updates to Rust code C-cleanup Category: This is a cleanup C-security Category: Security issues labels Mar 25, 2021
@teor2345 teor2345 added this to the 2021 Sprint 6 milestone Mar 25, 2021
@teor2345 teor2345 self-assigned this Mar 25, 2021
Comment on lines -127 to +177
/// 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(),
}
Copy link
Contributor Author

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 new MetaAddr, 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,
Copy link
Contributor Author

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()`.
@teor2345
Copy link
Contributor Author

Re-running jobs due to a cargo download failure.

@teor2345 teor2345 merged commit 1a159df into ZcashFoundation:main Mar 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-rust Area: Updates to Rust code C-bug Category: This is a bug C-cleanup Category: This is a cleanup C-security Category: Security issues
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants