From 30d24b23a187e2e64a1869b2d4bd6c865638160a Mon Sep 17 00:00:00 2001 From: Yuki Kishimoto Date: Sun, 14 Jan 2024 18:05:29 +0100 Subject: [PATCH] nostr: allow `client` and `relays` messages to be longer than expected during deserialization A relay is sending a 3rd argument in `EOSE` message causing issues with deserialization. Checking if the message array len is `>= X` fix this and potentially others issues in the future. --- crates/nostr/src/message/client.rs | 72 ++++++++-------- crates/nostr/src/message/relay/raw.rs | 119 +++++++++++++------------- 2 files changed, 98 insertions(+), 93 deletions(-) diff --git a/crates/nostr/src/message/client.rs b/crates/nostr/src/message/client.rs index e92b2fd65..baeb6c9ab 100644 --- a/crates/nostr/src/message/client.rs +++ b/crates/nostr/src/message/client.rs @@ -223,11 +223,12 @@ impl ClientMessage { // Event // ["EVENT", ] if v[0] == "EVENT" { - if v_len != 2 { + if v_len >= 2 { + let event = Event::from_value(v[1].clone())?; + return Ok(Self::new_event(event)); + } else { return Err(MessageHandleError::InvalidMessageFormat); } - let event = Event::from_value(v[1].clone())?; - return Ok(Self::new_event(event)); } // Req @@ -262,67 +263,70 @@ impl ClientMessage { // Close // ["CLOSE", ] if v[0] == "CLOSE" { - if v_len != 2 { + if v_len >= 2 { + let subscription_id: SubscriptionId = serde_json::from_value(v[1].clone())?; + return Ok(Self::close(subscription_id)); + } else { return Err(MessageHandleError::InvalidMessageFormat); } - - let subscription_id: SubscriptionId = serde_json::from_value(v[1].clone())?; - - return Ok(Self::close(subscription_id)); } // Auth // ["AUTH", ] if v[0] == "AUTH" { - if v_len != 2 { + if v_len >= 2 { + let event = Event::from_value(v[1].clone())?; + return Ok(Self::new_auth(event)); + } else { return Err(MessageHandleError::InvalidMessageFormat); } - let event = Event::from_value(v[1].clone())?; - return Ok(Self::new_auth(event)); } // Negentropy Open // ["NEG-OPEN", , , , ] if v[0] == "NEG-OPEN" { - if v_len != 5 { + if v_len >= 5 { + let subscription_id: SubscriptionId = serde_json::from_value(v[1].clone())?; + let filter: Filter = Filter::from_json(v[2].to_string())?; + let id_size: u8 = + v[3].as_u64() + .ok_or(MessageHandleError::InvalidMessageFormat)? as u8; + let initial_message: String = serde_json::from_value(v[4].clone())?; + return Ok(Self::NegOpen { + subscription_id, + filter: Box::new(filter), + id_size, + initial_message, + }); + } else { return Err(MessageHandleError::InvalidMessageFormat); } - let subscription_id: SubscriptionId = serde_json::from_value(v[1].clone())?; - let filter: Filter = Filter::from_json(v[2].to_string())?; - let id_size: u8 = - v[3].as_u64() - .ok_or(MessageHandleError::InvalidMessageFormat)? as u8; - let initial_message: String = serde_json::from_value(v[4].clone())?; - return Ok(Self::NegOpen { - subscription_id, - filter: Box::new(filter), - id_size, - initial_message, - }); } // Negentropy Message // ["NEG-MSG", , ] if v[0] == "NEG-MSG" { - if v_len != 3 { + if v_len >= 3 { + let subscription_id: SubscriptionId = serde_json::from_value(v[1].clone())?; + let message: String = serde_json::from_value(v[2].clone())?; + return Ok(Self::NegMsg { + subscription_id, + message, + }); + } else { return Err(MessageHandleError::InvalidMessageFormat); } - let subscription_id: SubscriptionId = serde_json::from_value(v[1].clone())?; - let message: String = serde_json::from_value(v[2].clone())?; - return Ok(Self::NegMsg { - subscription_id, - message, - }); } // Negentropy Close // ["NEG-CLOSE", ] if v[0] == "NEG-CLOSE" { - if v_len != 2 { + if v_len >= 2 { + let subscription_id: SubscriptionId = serde_json::from_value(v[1].clone())?; + return Ok(Self::NegClose { subscription_id }); + } else { return Err(MessageHandleError::InvalidMessageFormat); } - let subscription_id: SubscriptionId = serde_json::from_value(v[1].clone())?; - return Ok(Self::NegClose { subscription_id }); } Err(MessageHandleError::InvalidMessageFormat) diff --git a/crates/nostr/src/message/relay/raw.rs b/crates/nostr/src/message/relay/raw.rs index 48b4aa3b2..f9911bc22 100644 --- a/crates/nostr/src/message/relay/raw.rs +++ b/crates/nostr/src/message/relay/raw.rs @@ -87,122 +87,123 @@ impl RawRelayMessage { // Notice // Relay response format: ["NOTICE", ] if v[0] == "NOTICE" { - if v_len != 2 { + if v_len >= 2 { + return Ok(Self::Notice { + message: serde_json::from_value(v[1].clone())?, + }); + } else { return Err(MessageHandleError::InvalidMessageFormat); } - return Ok(Self::Notice { - message: serde_json::from_value(v[1].clone())?, - }); } // Closed // Relay response format: ["CLOSED", , ] if v[0] == "CLOSED" { - if v_len != 3 { + if v_len >= 3 { + return Ok(Self::Closed { + subscription_id: serde_json::from_value(v[1].clone())?, + message: serde_json::from_value(v[2].clone())?, + }); + } else { return Err(MessageHandleError::InvalidMessageFormat); } - - return Ok(Self::Closed { - subscription_id: serde_json::from_value(v[1].clone())?, - message: serde_json::from_value(v[2].clone())?, - }); } // Event // Relay response format: ["EVENT", , ] if v[0] == "EVENT" { - if v_len != 3 { + if v_len >= 3 { + return Ok(Self::Event { + subscription_id: serde_json::from_value(v[1].clone())?, + event: v[2].clone(), + }); + } else { return Err(MessageHandleError::InvalidMessageFormat); } - - return Ok(Self::Event { - subscription_id: serde_json::from_value(v[1].clone())?, - event: v[2].clone(), - }); } // EOSE (NIP-15) // Relay response format: ["EOSE", ] if v[0] == "EOSE" { - if v_len != 2 { + if v_len >= 2 { + let subscription_id: String = serde_json::from_value(v[1].clone())?; + return Ok(Self::EndOfStoredEvents(subscription_id)); + } else { return Err(MessageHandleError::InvalidMessageFormat); } - - let subscription_id: String = serde_json::from_value(v[1].clone())?; - return Ok(Self::EndOfStoredEvents(subscription_id)); } // OK (NIP-20) // Relay response format: ["OK", , , ] if v[0] == "OK" { - if v_len != 4 { + if v_len >= 4 { + return Ok(Self::Ok { + event_id: serde_json::from_value(v[1].clone())?, + status: serde_json::from_value(v[2].clone())?, + message: serde_json::from_value(v[3].clone())?, + }); + } else { return Err(MessageHandleError::InvalidMessageFormat); } - - return Ok(Self::Ok { - event_id: serde_json::from_value(v[1].clone())?, - status: serde_json::from_value(v[2].clone())?, - message: serde_json::from_value(v[3].clone())?, - }); } // OK (NIP-42) // Relay response format: ["AUTH", ] if v[0] == "AUTH" { - if v_len != 2 { + if v_len >= 2 { + return Ok(Self::Auth { + challenge: serde_json::from_value(v[1].clone())?, + }); + } else { return Err(MessageHandleError::InvalidMessageFormat); } - - return Ok(Self::Auth { - challenge: serde_json::from_value(v[1].clone())?, - }); } // Relay response format: ["EVENT", , ] if v[0] == "COUNT" { - if v_len != 3 { + if v_len >= 3 { + let map = v[2] + .as_object() + .ok_or(MessageHandleError::InvalidMessageFormat)?; + let count: Value = map + .get("count") + .ok_or(MessageHandleError::InvalidMessageFormat)? + .clone(); + let count: usize = serde_json::from_value(count)?; + + return Ok(Self::Count { + subscription_id: serde_json::from_value(v[1].clone())?, + count, + }); + } else { return Err(MessageHandleError::InvalidMessageFormat); } - - let map = v[2] - .as_object() - .ok_or(MessageHandleError::InvalidMessageFormat)?; - let count: Value = map - .get("count") - .ok_or(MessageHandleError::InvalidMessageFormat)? - .clone(); - let count: usize = serde_json::from_value(count)?; - - return Ok(Self::Count { - subscription_id: serde_json::from_value(v[1].clone())?, - count, - }); } // Negentropy Message // ["NEG-MSG", , ] if v[0] == "NEG-MSG" { - if v_len != 3 { + if v_len >= 3 { + return Ok(Self::NegMsg { + subscription_id: serde_json::from_value(v[1].clone())?, + message: serde_json::from_value(v[2].clone())?, + }); + } else { return Err(MessageHandleError::InvalidMessageFormat); } - - return Ok(Self::NegMsg { - subscription_id: serde_json::from_value(v[1].clone())?, - message: serde_json::from_value(v[2].clone())?, - }); } // Negentropy Error // ["NEG-ERR", , ] if v[0] == "NEG-ERR" { - if v_len != 3 { + if v_len >= 3 { + return Ok(Self::NegErr { + subscription_id: serde_json::from_value(v[1].clone())?, + code: serde_json::from_value(v[2].clone())?, + }); + } else { return Err(MessageHandleError::InvalidMessageFormat); } - - return Ok(Self::NegErr { - subscription_id: serde_json::from_value(v[1].clone())?, - code: serde_json::from_value(v[2].clone())?, - }); } Err(MessageHandleError::InvalidMessageFormat)