Improve error message, allow local IP federation via env var (#158)
* Improve error message, allow local IP federation via env var (fixes #152) * fix
This commit is contained in:
parent
d1f4da4198
commit
eca8f0fc6f
2 changed files with 20 additions and 17 deletions
|
|
@ -23,6 +23,7 @@ use crate::{
|
|||
use async_trait::async_trait;
|
||||
use derive_builder::Builder;
|
||||
use dyn_clone::{clone_trait_object, DynClone};
|
||||
use itertools::Itertools;
|
||||
use moka::future::Cache;
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
|
|
@ -185,27 +186,26 @@ impl<T: Clone> FederationConfig<T> {
|
|||
// Resolve domain and see if it points to private IP
|
||||
// TODO: Use is_global() once stabilized
|
||||
// https://doc.rust-lang.org/std/net/enum.IpAddr.html#method.is_global
|
||||
let invalid_ip =
|
||||
lookup_host((domain.to_owned(), 80))
|
||||
.await?
|
||||
.any(|addr| match addr.ip() {
|
||||
IpAddr::V4(addr) => {
|
||||
addr.is_private()
|
||||
|| addr.is_link_local()
|
||||
|| addr.is_loopback()
|
||||
|| addr.is_multicast()
|
||||
}
|
||||
IpAddr::V6(addr) => {
|
||||
addr.is_loopback()
|
||||
let mut ips = lookup_host((domain.to_owned(), 80)).await?;
|
||||
let allow_local = std::env::var("DANGER_FEDERATION_ALLOW_LOCAL_IP").is_ok();
|
||||
let invalid_ip = !allow_local
|
||||
&& ips.any(|addr| match addr.ip() {
|
||||
IpAddr::V4(addr) => {
|
||||
addr.is_private()
|
||||
|| addr.is_link_local()
|
||||
|| addr.is_loopback()
|
||||
|| addr.is_multicast()
|
||||
}
|
||||
IpAddr::V6(addr) => {
|
||||
addr.is_loopback()
|
||||
|| addr.is_multicast()
|
||||
|| ((addr.segments()[0] & 0xfe00) == 0xfc00) // is_unique_local
|
||||
|| ((addr.segments()[0] & 0xffc0) == 0xfe80) // is_unicast_link_local
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
if invalid_ip {
|
||||
return Err(Error::UrlVerificationError(
|
||||
"Localhost is only allowed in debug mode",
|
||||
));
|
||||
let ip_addrs = ips.join(", ");
|
||||
return Err(Error::DomainResolveError(domain.to_string(), ip_addrs));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@ pub enum Error {
|
|||
/// url verification error
|
||||
#[error("URL failed verification: {0}")]
|
||||
UrlVerificationError(&'static str),
|
||||
/// Resolving domain points to local IP.
|
||||
#[error("Resolving domain {0} points to local IP {1}. This may indicate an attacker attempting to access internal services. If intentional, you can ignore this error by setting DANGER_FEDERATION_ALLOW_LOCAL_IP=1")]
|
||||
DomainResolveError(String, String),
|
||||
/// Incoming activity has invalid digest for body
|
||||
#[error("Incoming activity has invalid digest for body")]
|
||||
ActivityBodyDigestInvalid,
|
||||
|
|
|
|||
Loading…
Reference in a new issue