From 6ffc54e241548f50fd26fa464e21c643ea7b6de1 Mon Sep 17 00:00:00 2001 From: strawberry Date: Wed, 17 Jan 2024 23:18:10 -0500 Subject: [PATCH] support blocking servers from fetching remote media from akin to synapse's `prevent_media_downloads_from` Signed-off-by: strawberry --- DIFFERENCES.md | 3 ++- src/api/client_server/media.rs | 23 +++++++++++++++++++++++ src/config/mod.rs | 10 ++++++++++ src/service/globals/mod.rs | 4 ++++ 4 files changed, 39 insertions(+), 1 deletion(-) diff --git a/DIFFERENCES.md b/DIFFERENCES.md index 1fa3577d..a4bfccc7 100644 --- a/DIFFERENCES.md +++ b/DIFFERENCES.md @@ -52,4 +52,5 @@ - Only follow 6 redirects total in our default reqwest ClientBuilder - Generate passwords with 25 characters instead of 15 - Add missing `reason` field to user ban events (`/ban`) -- For all [`/report`](https://spec.matrix.org/v1.9/client-server-api/#post_matrixclientv3roomsroomidreporteventid) requests: check if the reported event ID belongs to the reported room ID, raise report reasoning character limit to 750, fix broken formatting, make a small delayed random response per spec suggestion on privacy, and check if the sender user is in the reported room. \ No newline at end of file +- For all [`/report`](https://spec.matrix.org/v1.9/client-server-api/#post_matrixclientv3roomsroomidreporteventid) requests: check if the reported event ID belongs to the reported room ID, raise report reasoning character limit to 750, fix broken formatting, make a small delayed random response per spec suggestion on privacy, and check if the sender user is in the reported room. +- Support blocking servers from downloading remote media from \ No newline at end of file diff --git a/src/api/client_server/media.rs b/src/api/client_server/media.rs index 4eb01d35..0cf3eefb 100644 --- a/src/api/client_server/media.rs +++ b/src/api/client_server/media.rs @@ -8,6 +8,7 @@ use ruma::api::client::{ get_media_config, }, }; +use tracing::info; /// generated MXC ID (`media-id`) length const MXC_LENGTH: usize = 32; @@ -65,6 +66,17 @@ pub async fn get_remote_content( server_name: &ruma::ServerName, media_id: String, ) -> Result { + // we'll lie to the client and say the blocked server's media was not found and log. + // the client has no way of telling anyways so this is a security bonus. + if services() + .globals + .prevent_media_downloads_from() + .contains(&server_name.to_owned()) + { + info!("Received request for remote media `{}` but server is in our media server blocklist. Returning 404.", mxc); + return Err(Error::BadRequest(ErrorKind::NotFound, "Media not found.")); + } + let content_response = services() .sending .send_federation_request( @@ -189,6 +201,17 @@ pub async fn get_content_thumbnail_route( cross_origin_resource_policy: Some("cross-origin".to_owned()), }) } else if &*body.server_name != services().globals.server_name() && body.allow_remote { + // we'll lie to the client and say the blocked server's media was not found and log. + // the client has no way of telling anyways so this is a security bonus. + if services() + .globals + .prevent_media_downloads_from() + .contains(&body.server_name.to_owned()) + { + info!("Received request for remote media `{}` but server is in our media server blocklist. Returning 404.", mxc); + return Err(Error::BadRequest(ErrorKind::NotFound, "Media not found.")); + } + let get_thumbnail_response = services() .sending .send_federation_request( diff --git a/src/config/mod.rs b/src/config/mod.rs index 05101997..343e5ea3 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -128,6 +128,9 @@ pub struct Config { #[serde(default)] pub allow_guest_registration: bool, + #[serde(default = "Vec::new")] + pub prevent_media_downloads_from: Vec, + #[serde(flatten)] pub catchall: BTreeMap, } @@ -305,6 +308,13 @@ impl fmt::Display for Config { "RocksDB database optimize for spinning disks", &self.rocksdb_optimize_for_spinning_disks.to_string(), ), + ("Prevent Media Downloads From", { + let mut lst = vec![]; + for domain in &self.prevent_media_downloads_from { + lst.push(domain.host()); + } + &lst.join(", ") + }), ]; let mut msg: String = "Active config values:\n\n".to_owned(); diff --git a/src/service/globals/mod.rs b/src/service/globals/mod.rs index 46d83206..ad8f4a4c 100644 --- a/src/service/globals/mod.rs +++ b/src/service/globals/mod.rs @@ -423,6 +423,10 @@ impl Service<'_> { self.config.rocksdb_optimize_for_spinning_disks } + pub fn prevent_media_downloads_from(&self) -> &[OwnedServerName] { + &self.config.prevent_media_downloads_from + } + pub fn supported_room_versions(&self) -> Vec { let mut room_versions: Vec = vec![]; room_versions.extend(self.stable_room_versions.clone());