[0.5] Add IP checks (#163)
* [0.5] Add IP checks * add lockfile * replace * fix deps * ci
This commit is contained in:
parent
eca8f0fc6f
commit
cb05faefdc
3 changed files with 2998 additions and 15 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,6 +1,5 @@
|
||||||
/target
|
/target
|
||||||
/.idea
|
/.idea
|
||||||
/Cargo.lock
|
|
||||||
perf.data*
|
perf.data*
|
||||||
flamegraph.svg
|
flamegraph.svg
|
||||||
|
|
||||||
|
|
|
||||||
2970
Cargo.lock
generated
Normal file
2970
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -32,7 +32,7 @@ use reqwest_middleware::ClientWithMiddleware;
|
||||||
use rsa::{pkcs8::DecodePrivateKey, RsaPrivateKey};
|
use rsa::{pkcs8::DecodePrivateKey, RsaPrivateKey};
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
use std::{
|
use std::{
|
||||||
net::IpAddr,
|
net::{IpAddr, Ipv4Addr, Ipv6Addr},
|
||||||
ops::Deref,
|
ops::Deref,
|
||||||
sync::{
|
sync::{
|
||||||
atomic::{AtomicU32, Ordering},
|
atomic::{AtomicU32, Ordering},
|
||||||
|
|
@ -189,19 +189,9 @@ impl<T: Clone> FederationConfig<T> {
|
||||||
let mut ips = lookup_host((domain.to_owned(), 80)).await?;
|
let mut ips = lookup_host((domain.to_owned(), 80)).await?;
|
||||||
let allow_local = std::env::var("DANGER_FEDERATION_ALLOW_LOCAL_IP").is_ok();
|
let allow_local = std::env::var("DANGER_FEDERATION_ALLOW_LOCAL_IP").is_ok();
|
||||||
let invalid_ip = !allow_local
|
let invalid_ip = !allow_local
|
||||||
&& ips.any(|addr| match addr.ip() {
|
&& ips.any(|addr| match addr.ip().to_canonical() {
|
||||||
IpAddr::V4(addr) => {
|
IpAddr::V4(addr) => v4_is_invalid(addr),
|
||||||
addr.is_private()
|
IpAddr::V6(addr) => v6_is_invalid(addr),
|
||||||
|| 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 {
|
if invalid_ip {
|
||||||
let ip_addrs = ips.join(", ");
|
let ip_addrs = ips.join(", ");
|
||||||
|
|
@ -245,6 +235,30 @@ impl<T: Clone> FederationConfig<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn v4_is_invalid(v4: Ipv4Addr) -> bool {
|
||||||
|
v4.is_private()
|
||||||
|
|| v4.is_loopback()
|
||||||
|
|| v4.is_link_local()
|
||||||
|
|| v4.is_multicast()
|
||||||
|
|| v4.is_documentation()
|
||||||
|
|| v4.is_unspecified()
|
||||||
|
|| v4.is_broadcast()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn v6_is_invalid(v6: Ipv6Addr) -> bool {
|
||||||
|
let is_documentation = matches!(
|
||||||
|
v6.segments(),
|
||||||
|
[0x2001, 0xdb8, ..] | [0x3fff, 0..=0x0fff, ..]
|
||||||
|
);
|
||||||
|
is_documentation
|
||||||
|
|| v6.is_loopback()
|
||||||
|
|| v6.is_multicast()
|
||||||
|
|| (v6.segments()[0] & 0xfe00) == 0xfc00 // is_unique_local
|
||||||
|
|| (v6.segments()[0] & 0xffc0) == 0xfe80 // is_unicast_link_local
|
||||||
|
|| v6.is_unspecified()
|
||||||
|
|| v6.to_ipv4_mapped().is_some_and(v4_is_invalid)
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: Clone> FederationConfigBuilder<T> {
|
impl<T: Clone> FederationConfigBuilder<T> {
|
||||||
/// Sets an actor to use to sign all federated fetch requests
|
/// Sets an actor to use to sign all federated fetch requests
|
||||||
pub fn signed_fetch_actor<A: Actor>(&mut self, actor: &A) -> &mut Self {
|
pub fn signed_fetch_actor<A: Actor>(&mut self, actor: &A) -> &mut Self {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue