add config option for url_preview_domain_explicit_denylist

Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
strawberry 2024-04-14 21:12:48 -04:00 committed by June
parent 287887224f
commit d1c139de26
4 changed files with 38 additions and 6 deletions

View file

@ -240,7 +240,7 @@ allow_device_name_federation = false
url_preview_domain_contains_allowlist = []
# Vector list of explicit domains allowed to send requests to for URL previews. Defaults to none.
# Note: This is an *explicit* match, not a ccontains match. Putting "google.com" will match "https://google.com", "http://google.com", but not "https://mymaliciousdomainexamplegoogle.com"
# Note: This is an *explicit* match, not a contains match. Putting "google.com" will match "https://google.com", "http://google.com", but not "https://mymaliciousdomainexamplegoogle.com"
# Setting this to "*" will allow all URL previews. Please note that this opens up significant attack surface to your server, you are expected to be aware of the risks by doing so.
url_preview_domain_explicit_allowlist = []
@ -249,6 +249,11 @@ url_preview_domain_explicit_allowlist = []
# Setting this to "*" will allow all URL previews. Please note that this opens up significant attack surface to your server, you are expected to be aware of the risks by doing so.
url_preview_url_contains_allowlist = []
# Vector list of explicit domains not allowed to send requests to for URL previews. Defaults to none.
# Note: This is an *explicit* match, not a contains match. Putting "google.com" will match "https://google.com", "http://google.com", but not "https://mymaliciousdomainexamplegoogle.com"
# The denylist is checked first before allowlist. Setting this to "*" will not do anything.
url_preview_domain_explicit_denylist = []
# Maximum amount of bytes allowed in a URL preview body size when spidering. Defaults to 384KB (384_000 bytes)
url_preview_max_spider_size = 384_000

View file

@ -800,6 +800,7 @@ fn url_preview_allowed(url_str: &str) -> bool {
let allowlist_domain_contains = services().globals.url_preview_domain_contains_allowlist();
let allowlist_domain_explicit = services().globals.url_preview_domain_explicit_allowlist();
let denylist_domain_explicit = services().globals.url_preview_domain_explicit_denylist();
let allowlist_url_contains = services().globals.url_preview_url_contains_allowlist();
if allowlist_domain_contains.contains(&"*".to_owned())
@ -811,8 +812,16 @@ fn url_preview_allowed(url_str: &str) -> bool {
}
if !host.is_empty() {
if denylist_domain_explicit.contains(&host) {
debug!(
"Host {} is not allowed by url_preview_domain_explicit_denylist (check 1/4)",
&host
);
return false;
}
if allowlist_domain_explicit.contains(&host) {
debug!("Host {} is allowed by url_preview_domain_explicit_allowlist (check 1/3)", &host);
debug!("Host {} is allowed by url_preview_domain_explicit_allowlist (check 2/4)", &host);
return true;
}
@ -820,7 +829,7 @@ fn url_preview_allowed(url_str: &str) -> bool {
.iter()
.any(|domain_s| domain_s.contains(&host.clone()))
{
debug!("Host {} is allowed by url_preview_domain_contains_allowlist (check 2/3)", &host);
debug!("Host {} is allowed by url_preview_domain_contains_allowlist (check 3/4)", &host);
return true;
}
@ -828,7 +837,7 @@ fn url_preview_allowed(url_str: &str) -> bool {
.iter()
.any(|url_s| url.to_string().contains(&url_s.to_string()))
{
debug!("URL {} is allowed by url_preview_url_contains_allowlist (check 3/3)", &host);
debug!("URL {} is allowed by url_preview_url_contains_allowlist (check 4/4)", &host);
return true;
}
@ -838,9 +847,17 @@ fn url_preview_allowed(url_str: &str) -> bool {
match host.split_once('.') {
None => return false,
Some((_, root_domain)) => {
if denylist_domain_explicit.contains(&root_domain.to_owned()) {
debug!(
"Root domain {} is not allowed by url_preview_domain_explicit_denylist (check 1/3)",
&root_domain
);
return true;
}
if allowlist_domain_explicit.contains(&root_domain.to_owned()) {
debug!(
"Root domain {} is allowed by url_preview_domain_explicit_allowlist (check 1/3)",
"Root domain {} is allowed by url_preview_domain_explicit_allowlist (check 2/3)",
&root_domain
);
return true;
@ -851,7 +868,7 @@ fn url_preview_allowed(url_str: &str) -> bool {
.any(|domain_s| domain_s.contains(&root_domain.to_owned()))
{
debug!(
"Root domain {} is allowed by url_preview_domain_contains_allowlist (check 2/3)",
"Root domain {} is allowed by url_preview_domain_contains_allowlist (check 3/3)",
&root_domain
);
return true;

View file

@ -278,6 +278,8 @@ pub struct Config {
#[serde(default = "Vec::new")]
pub url_preview_domain_explicit_allowlist: Vec<String>,
#[serde(default = "Vec::new")]
pub url_preview_domain_explicit_denylist: Vec<String>,
#[serde(default = "Vec::new")]
pub url_preview_url_contains_allowlist: Vec<String>,
#[serde(default = "default_url_preview_max_spider_size")]
pub url_preview_max_spider_size: usize,
@ -709,6 +711,10 @@ impl fmt::Display for Config {
"URL preview domain explicit allowlist",
&self.url_preview_domain_explicit_allowlist.join(", "),
),
(
"URL preview domain explicit denylist",
&self.url_preview_domain_explicit_denylist.join(", "),
),
(
"URL preview URL contains allowlist",
&self.url_preview_url_contains_allowlist.join(", "),

View file

@ -277,6 +277,10 @@ impl Service<'_> {
&self.config.url_preview_domain_explicit_allowlist
}
pub fn url_preview_domain_explicit_denylist(&self) -> &Vec<String> {
&self.config.url_preview_domain_explicit_denylist
}
pub fn url_preview_url_contains_allowlist(&self) -> &Vec<String> { &self.config.url_preview_url_contains_allowlist }
pub fn url_preview_max_spider_size(&self) -> usize { self.config.url_preview_max_spider_size }