From 32ab88e68a3fe1c2b0f70d7cc363d6d0a2bf7e8a Mon Sep 17 00:00:00 2001 From: strawberry Date: Sun, 24 Mar 2024 18:33:25 -0400 Subject: [PATCH] check the URL and response remote address for ip_range_denylist the previous only checked the server_name Signed-off-by: strawberry --- src/api/appservice_server.rs | 22 ++++++++++++++++++- src/api/server_server.rs | 37 ++++++++++++++++++++++++++++++++ src/main.rs | 2 +- src/service/pusher/mod.rs | 41 +++++++++++++++++++++++++++++++++++- 4 files changed, 99 insertions(+), 3 deletions(-) diff --git a/src/api/appservice_server.rs b/src/api/appservice_server.rs index 6b3a4152..927d0612 100644 --- a/src/api/appservice_server.rs +++ b/src/api/appservice_server.rs @@ -1,8 +1,9 @@ use std::{fmt::Debug, mem, time::Duration}; use bytes::BytesMut; +use ipaddress::IPAddress; use ruma::api::{appservice::Registration, IncomingResponse, MatrixVersion, OutgoingRequest, SendAccessToken}; -use tracing::warn; +use tracing::{debug, warn}; use crate::{services, utils, Error, Result}; @@ -44,6 +45,25 @@ where *reqwest_request.timeout_mut() = Some(Duration::from_secs(120)); let url = reqwest_request.url().clone(); + + if let Some(url_host) = url.host_str() { + debug!("Checking request URL for IP"); + if let Ok(ip) = IPAddress::parse(url_host) { + let cidr_ranges_s = services().globals.ip_range_denylist().to_vec(); + let mut cidr_ranges: Vec = Vec::new(); + + for cidr in cidr_ranges_s { + cidr_ranges.push(IPAddress::parse(cidr).expect("we checked this at startup")); + } + + for cidr in cidr_ranges { + if cidr.includes(&ip) { + return Some(Err(Error::BadServerResponse("Not allowed to send requests to this IP"))); + } + } + } + } + let mut response = match services().globals.client.appservice.execute(reqwest_request).await { Ok(r) => r, Err(e) => { diff --git a/src/api/server_server.rs b/src/api/server_server.rs index 919f30c4..4ead87c0 100644 --- a/src/api/server_server.rs +++ b/src/api/server_server.rs @@ -238,6 +238,24 @@ where let url = reqwest_request.url().clone(); + if let Some(url_host) = url.host_str() { + debug!("Checking request URL for IP"); + if let Ok(ip) = IPAddress::parse(url_host) { + let cidr_ranges_s = services().globals.ip_range_denylist().to_vec(); + let mut cidr_ranges: Vec = Vec::new(); + + for cidr in cidr_ranges_s { + cidr_ranges.push(IPAddress::parse(cidr).expect("we checked this at startup")); + } + + for cidr in cidr_ranges { + if cidr.includes(&ip) { + return Err(Error::BadServerResponse("Not allowed to send requests to this IP")); + } + } + } + } + debug!("Sending request to {destination} at {url}"); let response = services().globals.client.federation.execute(reqwest_request).await; debug!("Received response from {destination} at {url}"); @@ -245,6 +263,25 @@ where match response { Ok(mut response) => { // reqwest::Response -> http::Response conversion + + debug!("Checking response destination's IP"); + if let Some(remote_addr) = response.remote_addr() { + if let Ok(ip) = IPAddress::parse(remote_addr.ip().to_string()) { + let cidr_ranges_s = services().globals.ip_range_denylist().to_vec(); + let mut cidr_ranges: Vec = Vec::new(); + + for cidr in cidr_ranges_s { + cidr_ranges.push(IPAddress::parse(cidr).expect("we checked this at startup")); + } + + for cidr in cidr_ranges { + if cidr.includes(&ip) { + return Err(Error::BadServerResponse("Not allowed to send requests to this IP")); + } + } + } + } + let status = response.status(); let mut http_response_builder = http::Response::builder().status(status).version(response.version()); mem::swap( diff --git a/src/main.rs b/src/main.rs index d6bf1d93..aa95ef53 100644 --- a/src/main.rs +++ b/src/main.rs @@ -248,7 +248,7 @@ async fn main() { // check if user specified valid IP CIDR ranges on startup for cidr in services().globals.ip_range_denylist() { - let _ = ipaddress::IPAddress::parse(cidr).map_err(|e| error!("Error parsing specified IP CIDR range: {e}")); + _ = ipaddress::IPAddress::parse(cidr).map_err(|e| error!("Error parsing specified IP CIDR range: {e}")); } if config.allow_registration diff --git a/src/service/pusher/mod.rs b/src/service/pusher/mod.rs index 47d5572f..91170b97 100644 --- a/src/service/pusher/mod.rs +++ b/src/service/pusher/mod.rs @@ -3,6 +3,7 @@ use std::{fmt::Debug, mem}; use bytes::BytesMut; pub use data::Data; +use ipaddress::IPAddress; use ruma::{ api::{ client::push::{set_pusher, Pusher, PusherKind}, @@ -19,7 +20,7 @@ use ruma::{ serde::Raw, uint, RoomId, UInt, UserId, }; -use tracing::{info, warn}; +use tracing::{debug, info, warn}; use crate::{services, Error, PduEvent, Result}; @@ -63,11 +64,49 @@ impl Service { //*reqwest_request.timeout_mut() = Some(Duration::from_secs(5)); let url = reqwest_request.url().clone(); + + if let Some(url_host) = url.host_str() { + debug!("Checking request URL for IP"); + if let Ok(ip) = IPAddress::parse(url_host) { + let cidr_ranges_s = services().globals.ip_range_denylist().to_vec(); + let mut cidr_ranges: Vec = Vec::new(); + + for cidr in cidr_ranges_s { + cidr_ranges.push(IPAddress::parse(cidr).expect("we checked this at startup")); + } + + for cidr in cidr_ranges { + if cidr.includes(&ip) { + return Err(Error::BadServerResponse("Not allowed to send requests to this IP")); + } + } + } + } + let response = services().globals.client.pusher.execute(reqwest_request).await; match response { Ok(mut response) => { // reqwest::Response -> http::Response conversion + + debug!("Checking response destination's IP"); + if let Some(remote_addr) = response.remote_addr() { + if let Ok(ip) = IPAddress::parse(remote_addr.ip().to_string()) { + let cidr_ranges_s = services().globals.ip_range_denylist().to_vec(); + let mut cidr_ranges: Vec = Vec::new(); + + for cidr in cidr_ranges_s { + cidr_ranges.push(IPAddress::parse(cidr).expect("we checked this at startup")); + } + + for cidr in cidr_ranges { + if cidr.includes(&ip) { + return Err(Error::BadServerResponse("Not allowed to send requests to this IP")); + } + } + } + } + let status = response.status(); let mut http_response_builder = http::Response::builder().status(status).version(response.version()); mem::swap(