more error checking for deserialising events and canonical JSON

Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
strawberry 2024-01-17 22:07:43 -05:00 committed by June
parent c83acabfb0
commit 1a06c8c9d3
3 changed files with 69 additions and 8 deletions

View file

@ -9,6 +9,7 @@ use ruma::{
},
events::{StateEventType, TimelineEventType},
};
use serde_json::from_str;
use std::{
collections::{BTreeMap, HashSet},
sync::Arc,
@ -48,6 +49,52 @@ pub async fn send_message_event_route(
));
}
// certain event types require certain fields to be valid in request bodies.
// this helps prevent attempting to handle events that we can't deserialise later so don't waste resources on it.
//
// see https://spec.matrix.org/v1.9/client-server-api/#events-2 for what's required per event type.
match body.event_type.to_string().into() {
TimelineEventType::RoomMessage => {
let body_field = body.body.body.get_field::<String>("body");
let msgtype_field = body.body.body.get_field::<String>("msgtype");
if body_field.is_err() {
return Err(Error::BadRequest(
ErrorKind::InvalidParam,
"'body' field in JSON request is invalid",
));
}
if msgtype_field.is_err() {
return Err(Error::BadRequest(
ErrorKind::InvalidParam,
"'msgtype' field in JSON request is invalid",
));
}
}
TimelineEventType::RoomName => {
let name_field = body.body.body.get_field::<String>("name");
if name_field.is_err() {
return Err(Error::BadRequest(
ErrorKind::InvalidParam,
"'name' field in JSON request is invalid",
));
}
}
TimelineEventType::RoomTopic => {
let topic_field = body.body.body.get_field::<String>("topic");
if topic_field.is_err() {
return Err(Error::BadRequest(
ErrorKind::InvalidParam,
"'topic' field in JSON request is invalid",
));
}
}
_ => {} // event may be custom/experimental or can be empty don't do anything with it
};
// Check if this is a new transaction id
if let Some(response) =
services()
@ -79,7 +126,7 @@ pub async fn send_message_event_route(
.build_and_append_pdu(
PduBuilder {
event_type: body.event_type.to_string().into(),
content: serde_json::from_str(body.body.body.json().get())
content: from_str(body.body.body.json().get())
.map_err(|_| Error::BadRequest(ErrorKind::BadJson, "Invalid JSON body."))?,
unsigned: Some(unsigned),
state_key: None,

View file

@ -1822,8 +1822,10 @@ pub async fn create_invite_route(
));
}
let mut signed_event = utils::to_canonical_object(&body.event)
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Invite event is invalid."))?;
let mut signed_event = utils::to_canonical_object(&body.event).map_err(|e| {
error!("Failed to convert invite event to canonical JSON: {}", e);
Error::BadRequest(ErrorKind::InvalidParam, "Invite event is invalid.")
})?;
ruma::signatures::hash_and_sign_event(
services().globals.server_name().as_str(),

View file

@ -260,8 +260,17 @@ impl Service {
unsigned.insert(
"prev_content".to_owned(),
CanonicalJsonValue::Object(
utils::to_canonical_object(prev_state.content.clone())
.expect("event is valid, we just created it"),
utils::to_canonical_object(prev_state.content.clone()).map_err(
|e| {
error!(
"Failed to convert prev_state to canonical JSON: {}",
e
);
Error::bad_database(
"Failed to convert prev_state to canonical JSON.",
)
},
)?,
),
);
}
@ -802,7 +811,7 @@ impl Service {
|k, s| auth_events.get(&(k.clone(), s.to_owned())),
)
.map_err(|e| {
error!("Auth check for PDU {:?} failed: {:?}", &pdu, e);
error!("Auth check failed: {:?}", e);
Error::bad_database("Auth check failed.")
})?;
@ -815,7 +824,7 @@ impl Service {
// Hash and sign
let mut pdu_json = utils::to_canonical_object(&pdu).map_err(|e| {
error!("Failed to convert PDU {:?} to canonical JSON: {}", &pdu, e);
error!("Failed to convert PDU to canonical JSON: {}", e);
Error::bad_database("Failed to convert PDU to canonical JSON.")
})?;
@ -1105,7 +1114,10 @@ impl Service {
pdu.redact(room_version_id, reason)?;
self.replace_pdu(
&pdu_id,
&utils::to_canonical_object(&pdu).expect("PDU is an object"),
&utils::to_canonical_object(&pdu).map_err(|e| {
error!("Failed to convert PDU to canonical JSON: {}", e);
Error::bad_database("Failed to convert PDU to canonical JSON.")
})?,
&pdu,
)?;
}