This commit is contained in:
Felix Ableitner 2025-01-09 11:56:29 +01:00
parent e4ea9abdb7
commit 451d388833
3 changed files with 21 additions and 20 deletions

View file

@ -29,7 +29,7 @@ pub async fn new_instance(
.signed_fetch_actor(&system_user) .signed_fetch_actor(&system_user)
.app_data(database) .app_data(database)
.url_verifier(Box::new(MyUrlVerifier())) .url_verifier(Box::new(MyUrlVerifier()))
.debug(true) .debug(false)
.build() .build()
.await?; .await?;
Ok(config) Ok(config)

View file

@ -26,8 +26,6 @@ use bytes::Bytes;
use derive_builder::Builder; use derive_builder::Builder;
use dyn_clone::{clone_trait_object, DynClone}; use dyn_clone::{clone_trait_object, DynClone};
use moka::future::Cache; use moka::future::Cache;
use once_cell::sync::Lazy;
use regex::Regex;
use reqwest::Request; use reqwest::Request;
use reqwest_middleware::{ClientWithMiddleware, RequestBuilder}; use reqwest_middleware::{ClientWithMiddleware, RequestBuilder};
use rsa::{pkcs8::DecodePrivateKey, RsaPrivateKey}; use rsa::{pkcs8::DecodePrivateKey, RsaPrivateKey};
@ -167,12 +165,6 @@ impl<T: Clone> FederationConfig<T> {
return Err(Error::UrlVerificationError("Url must have a domain")); return Err(Error::UrlVerificationError("Url must have a domain"));
}; };
static DOMAIN_REGEX: Lazy<Regex> =
Lazy::new(|| Regex::new(r"^[a-zA-Z0-9.-]*$").expect("compile regex"));
if !DOMAIN_REGEX.is_match(domain) {
return Err(Error::UrlVerificationError("Invalid characters in domain"));
}
// Extra checks only for production mode // Extra checks only for production mode
if !self.debug { if !self.debug {
if url.port().is_some() { if url.port().is_some() {
@ -182,20 +174,23 @@ impl<T: Clone> FederationConfig<T> {
// Resolve domain and see if it points to private IP // Resolve domain and see if it points to private IP
// TODO: Use is_global() once stabilized // TODO: Use is_global() once stabilized
// https://doc.rust-lang.org/std/net/enum.IpAddr.html#method.is_global // https://doc.rust-lang.org/std/net/enum.IpAddr.html#method.is_global
let invalid_ip = lookup_host(domain).await?.any(|addr| match addr.ip() { let invalid_ip =
IpAddr::V4(addr) => { lookup_host((domain.to_owned(), 80))
addr.is_private() .await?
|| addr.is_link_local() .any(|addr| match addr.ip() {
|| addr.is_loopback() IpAddr::V4(addr) => {
|| addr.is_multicast() addr.is_private()
} || addr.is_link_local()
IpAddr::V6(addr) => { || addr.is_loopback()
addr.is_loopback() || addr.is_multicast()
}
IpAddr::V6(addr) => {
addr.is_loopback()
|| addr.is_multicast() || addr.is_multicast()
|| ((addr.segments()[0] & 0xfe00) == 0xfc00) // is_unique_local || ((addr.segments()[0] & 0xfe00) == 0xfc00) // is_unique_local
|| ((addr.segments()[0] & 0xffc0) == 0xfe80) // is_unicast_link_local || ((addr.segments()[0] & 0xffc0) == 0xfe80) // is_unicast_link_local
} }
}); });
if invalid_ip { if invalid_ip {
return Err(Error::UrlVerificationError( return Err(Error::UrlVerificationError(
"Localhost is only allowed in debug mode", "Localhost is only allowed in debug mode",

View file

@ -50,10 +50,16 @@ where
for<'de2> <Kind as Object>::Kind: serde::Deserialize<'de2>, for<'de2> <Kind as Object>::Kind: serde::Deserialize<'de2>,
<Kind as Object>::Error: From<crate::error::Error> + Send + Sync + Display, <Kind as Object>::Error: From<crate::error::Error> + Send + Sync + Display,
{ {
static DOMAIN_REGEX: Lazy<Regex> =
Lazy::new(|| Regex::new(r"^[a-zA-Z0-9.-]*$").expect("compile regex"));
let (_, domain) = identifier let (_, domain) = identifier
.splitn(2, '@') .splitn(2, '@')
.collect_tuple() .collect_tuple()
.ok_or(WebFingerError::WrongFormat.into_crate_error())?; .ok_or(WebFingerError::WrongFormat.into_crate_error())?;
if !DOMAIN_REGEX.is_match(domain) {
return Err(Error::UrlVerificationError("Invalid characters in domain").into());
}
let protocol = if data.config.debug { "http" } else { "https" }; let protocol = if data.config.debug { "http" } else { "https" };
let fetch_url = let fetch_url =
format!("{protocol}://{domain}/.well-known/webfinger?resource=acct:{identifier}"); format!("{protocol}://{domain}/.well-known/webfinger?resource=acct:{identifier}");