From aa02a48db494b2e55b8ab71fcf26be1b3cb078be Mon Sep 17 00:00:00 2001 From: Wasif Iqbal Date: Tue, 2 Jul 2024 21:03:18 -0500 Subject: [PATCH] fix: validate gossip message for clock skew (#2119) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Motivation - Messages were found in gossip with very high timestamps that would be very far in the future ## Change Summary - Reject gossip messages that are more than 10 minutes in the future ## Merge Checklist _Choose all relevant options below by adding an `x` now or at any time before submitting for review_ - [x] PR title adheres to the [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) standard - [x] PR has a [changeset](https://github.com/farcasterxyz/hub-monorepo/blob/main/CONTRIBUTING.md#35-adding-changesets) - [x] PR has been tagged with a change label(s) (i.e. documentation, feature, bugfix, or chore) - [ ] PR includes [documentation](https://github.com/farcasterxyz/hub-monorepo/blob/main/CONTRIBUTING.md#32-writing-docs) if necessary. - [x] All [commits have been signed](https://github.com/farcasterxyz/hub-monorepo/blob/main/CONTRIBUTING.md#22-signing-commits) ## Additional Context If this is a relatively large or complex change, provide more details here that will help reviewers --- ## PR-Codex overview This PR focuses on fixing clock skew validation for gossip messages in the `@farcaster/hubble` module. ### Detailed summary - Added validation for clock skew in gossip messages - Introduced `ALLOWED_CLOCK_SKEW_SECONDS` constant - Improved error handling for future timestamps in gossip messages > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` --- .changeset/silent-planes-promise.md | 5 +++++ apps/hubble/src/hubble.ts | 20 +++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 .changeset/silent-planes-promise.md diff --git a/.changeset/silent-planes-promise.md b/.changeset/silent-planes-promise.md new file mode 100644 index 0000000000..9442bd517f --- /dev/null +++ b/.changeset/silent-planes-promise.md @@ -0,0 +1,5 @@ +--- +"@farcaster/hubble": patch +--- + +fix: validate gossip message for clock skew diff --git a/apps/hubble/src/hubble.ts b/apps/hubble/src/hubble.ts index caca74e9e9..2072dcc5ba 100644 --- a/apps/hubble/src/hubble.ts +++ b/apps/hubble/src/hubble.ts @@ -18,7 +18,6 @@ import { Message, OnChainEvent, onChainEventTypeToJSON, - toFarcasterTime, UserNameProof, validations, } from "@farcaster/hub-nodejs"; @@ -127,6 +126,7 @@ export const FARCASTER_VERSIONS_SCHEDULE: VersionSchedule[] = [ const MAX_CONTACT_INFO_AGE_MS = 1000 * 60 * 60; // 60 minutes const CONTACT_INFO_UPDATE_THRESHOLD_MS = 1000 * 60 * 30; // 30 minutes +const ALLOWED_CLOCK_SKEW_SECONDS = 60 * 10; // 10 minutes export interface HubInterface { engine: Engine; @@ -1274,6 +1274,24 @@ export class Hub implements HubInterface { const messageFirstGossipedTime = gossipMessage.timestamp ?? 0; const gossipMessageDelay = currentTime - messageFirstGossipedTime; if (gossipMessage.timestamp) { + if (gossipMessage.timestamp > currentTime && gossipMessage.timestamp - currentTime > ALLOWED_CLOCK_SKEW_SECONDS) { + log.error( + { + allowedClockSkew: ALLOWED_CLOCK_SKEW_SECONDS, + currentTime, + gossipMessageTimestamp: gossipMessage.timestamp, + source: source.toString(), + }, + "Received gossip message with future timestamp", + ); + await this.gossipNode.reportValid(msgId, peerIdFromString(source.toString()).toBytes(), false); + return err( + new HubError( + "bad_request.invalid_param", + "Invalid Farcaster timestamp in gossip message - future timestamp found in seconds from Farcaster Epoch", + ), + ); + } // If message is older than seenTTL, we will try to merge it, but report it as invalid so it doesn't // propogate across the network const cutOffTime = getFarcasterTime().unwrapOr(0) - GOSSIP_SEEN_TTL / 1000;