From d6991611f0d79d1ad4a1e3cdb5d1372a79b87ac7 Mon Sep 17 00:00:00 2001 From: strawberry Date: Sat, 26 Oct 2024 12:32:47 -0400 Subject: [PATCH] add `require_auth_for_profile_requests` config option, check endpoint metadata instead of request string Signed-off-by: strawberry --- src/api/router/auth.rs | 36 ++++++++++++++++++++++++++++++------ src/core/config/mod.rs | 11 ++++++++++- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/src/api/router/auth.rs b/src/api/router/auth.rs index 28d6bc55..6b1bb1a9 100644 --- a/src/api/router/auth.rs +++ b/src/api/router/auth.rs @@ -6,7 +6,15 @@ use axum_extra::{ }; use conduit::{debug_error, err, warn, Err, Error, Result}; use ruma::{ - api::{client::error::ErrorKind, AuthScheme, Metadata}, + api::{ + client::{ + directory::get_public_rooms, + error::ErrorKind, + profile::{get_avatar_url, get_display_name, get_profile, get_profile_key, get_timezone_key}, + voip::get_turn_server_info, + }, + AuthScheme, IncomingRequest, Metadata, + }, server_util::authorization::XMatrix, CanonicalJsonObject, CanonicalJsonValue, OwnedDeviceId, OwnedServerName, OwnedUserId, UserId, }; @@ -54,9 +62,8 @@ pub(super) async fn auth( }; if metadata.authentication == AuthScheme::None { - match request.parts.uri.path() { - // TODO: can we check this better? - "/_matrix/client/v3/publicRooms" | "/_matrix/client/r0/publicRooms" => { + match metadata { + &get_public_rooms::v3::Request::METADATA => { if !services .globals .config @@ -73,6 +80,23 @@ pub(super) async fn auth( } } }, + &get_profile::v3::Request::METADATA + | &get_profile_key::unstable::Request::METADATA + | &get_display_name::v3::Request::METADATA + | &get_avatar_url::v3::Request::METADATA + | &get_timezone_key::unstable::Request::METADATA => { + if services.globals.config.require_auth_for_profile_requests { + match token { + Token::Appservice(_) | Token::User(_) => { + // we should have validated the token above + // already + }, + Token::None | Token::Invalid => { + return Err(Error::BadRequest(ErrorKind::MissingToken, "Missing or invalid access token.")); + }, + } + } + }, _ => {}, }; } @@ -107,9 +131,9 @@ pub(super) async fn auth( appservice_info: Some(*info), }) }, - (AuthScheme::AccessToken, Token::None) => match request.parts.uri.path() { + (AuthScheme::AccessToken, Token::None) => match metadata { // TODO: can we check this better? - "/_matrix/client/v3/voip/turnServer" | "/_matrix/client/r0/voip/turnServer" => { + &get_turn_server_info::v3::Request::METADATA => { if services.globals.config.turn_allow_guests { Ok(Auth { origin: None, diff --git a/src/core/config/mod.rs b/src/core/config/mod.rs index ff214420..04e44fd7 100644 --- a/src/core/config/mod.rs +++ b/src/core/config/mod.rs @@ -58,7 +58,6 @@ pub struct Config { /// YOU NEED TO EDIT THIS pub server_name: OwnedServerName, - /// Database backend: Only rocksdb is supported. /// default address (IPv4 or IPv6) conduwuit will listen on. Generally you /// want this to be localhost (127.0.0.1 / ::1). If you are using Docker or /// a container NAT networking setup, you likely need this to be 0.0.0.0. @@ -94,6 +93,8 @@ pub struct Config { #[serde(default = "default_unix_socket_perms")] pub unix_socket_perms: u32, + /// Database backend: Only rocksdb is supported. + /// /// default: rocksdb #[serde(default = "default_database_backend")] pub database_backend: String, @@ -406,6 +407,14 @@ pub struct Config { #[serde(default)] pub federation_loopback: bool, + /// Set this to true to require authentication on the normally + /// unauthenticated profile retrieval endpoints (GET) + /// "/_matrix/client/v3/profile/{userId}". + /// + /// This can prevent profile scraping. + #[serde(default)] + pub require_auth_for_profile_requests: bool, + /// Set this to true to allow your server's public room directory to be /// federated. Set this to false to protect against /publicRooms spiders, /// but will forbid external users from viewing your server's public room