validate schema of new canonical alias events sent by clients

Previously, we would only attempt to validate the aliases in the event
content if we were able to parse the event, and would silently allow it
otherwise.
This commit is contained in:
Olivia Lee 2025-01-20 12:11:41 -08:00
parent c748c7c188
commit 051221c0ab
No known key found for this signature in database
GPG key ID: 54D568A15B9CD1F9
2 changed files with 34 additions and 25 deletions

View file

@ -225,6 +225,9 @@ This will be the first release of Grapevine since it was forked from Conduit
instead of 400 M_FORBIDDEN when trying to set a canonical alias that does
not exist.
([!158](https://gitlab.computer.surgery/matrix/grapevine/-/merge_requests/158))
26. Validate schema of new `m.room.canonical_alias` event sent by clients,
rather than silently allowing any contents if the event can't be parsed.
([!158](https://gitlab.computer.surgery/matrix/grapevine/-/merge_requests/158))
### Added

View file

@ -210,33 +210,39 @@ async fn send_state_event_for_key_helper(
) -> Result<Arc<EventId>> {
let sender_user = sender;
// TODO: Review this check, error if event is unparsable, use event type,
// allow alias if it previously existed
if let Ok(canonical_alias) = serde_json::from_str::<
RoomCanonicalAliasEventContent,
>(json.json().get())
{
let mut aliases = canonical_alias.alt_aliases.clone();
// TODO: allow alias if it previously existed
if event_type == &StateEventType::RoomCanonicalAlias {
if let Ok(canonical_alias) = serde_json::from_str::<
RoomCanonicalAliasEventContent,
>(json.json().get())
{
let mut aliases = canonical_alias.alt_aliases.clone();
if let Some(alias) = canonical_alias.alias {
aliases.push(alias);
}
for alias in aliases {
if alias.server_name() != services().globals.server_name()
|| services()
.rooms
.alias
.resolve_local_alias(&alias)?
.filter(|room| room == room_id)
.is_none()
{
return Err(Error::BadRequest(
ErrorKind::BadAlias,
"You are only allowed to send canonical_alias events when \
it's aliases already exists",
));
if let Some(alias) = canonical_alias.alias {
aliases.push(alias);
}
for alias in aliases {
if alias.server_name() != services().globals.server_name()
|| services()
.rooms
.alias
.resolve_local_alias(&alias)?
.filter(|room| room == room_id)
.is_none()
{
return Err(Error::BadRequest(
ErrorKind::BadAlias,
"You are only allowed to send canonical_alias events \
when it's aliases already exists",
));
}
}
} else {
return Err(Error::BadRequest(
ErrorKind::InvalidParam,
"m.room.canonical_alias event did not match expected schema",
));
}
}