Do not DNSBL check invalid domains (#1107)

This commit is contained in:
mdecimus
2025-01-19 18:36:48 +01:00
parent a6f11699ef
commit 5e5771e033
7 changed files with 108 additions and 30 deletions

View File

@@ -821,6 +821,18 @@ impl Element {
Element::Any => map,
}
}
pub fn as_str(&self) -> &'static str {
match self {
Element::Url => "url",
Element::Domain => "domain",
Element::Email => "email",
Element::Ip => "ip",
Element::Header => "header",
Element::Body => "body",
Element::Any => "any",
}
}
}
pub struct IpResolver {

View File

@@ -165,14 +165,12 @@ impl SpamFilterAnalyzeDomain for Server {
attributes.iter().find_map(|(attr, value)| {
if *attr == HREF {
let value = value.as_deref()?.strip_prefix("mailto:")?;
if value.contains('@') {
let email =
Email::new(value.split_once('?').map_or(value, |(e, _)| e));
if email.is_valid() {
return Some(ElementLocation::new(
Recipient {
email: Email::new(
value.split_once('?').map_or(value, |(e, _)| e),
),
name: None,
},
Recipient { email, name: None },
if is_body {
Location::BodyHtml
} else {
@@ -203,17 +201,19 @@ impl SpamFilterAnalyzeDomain for Server {
}
}
emails.insert(ElementLocation::new(
Recipient {
email: email.clone(),
name: None,
},
if is_body {
Location::BodyText
} else {
Location::Attachment
},
));
if email.is_valid() {
emails.insert(ElementLocation::new(
Recipient {
email: email.clone(),
name: None,
},
if is_body {
Location::BodyText
} else {
Location::Attachment
},
));
}
}
}
}

View File

@@ -250,14 +250,16 @@ impl SpamFilterAnalyzeUrl for Server {
}
// Check Domain DNSBL
check_dnsbl(
self,
ctx,
&StringResolver(host.sld_or_default()),
Element::Domain,
el.location,
)
.await;
if let Some(sld) = &host.sld {
check_dnsbl(
self,
ctx,
&StringResolver(sld),
Element::Domain,
el.location,
)
.await;
}
} else {
// URL is an ip address
ctx.result.add_tag("SUSPICIOUS_URL");

View File

@@ -55,6 +55,7 @@ pub(crate) async fn check_dnsbl(
server,
dnsbl,
SpamFilterResolver::new(ctx, resolver, location),
scope,
&mut checks,
)
.await
@@ -77,6 +78,7 @@ async fn is_dnsbl(
server: &Server,
config: &DnsBlServer,
resolver: SpamFilterResolver<'_, impl ResolveVariable>,
element: Element,
checks: &mut usize,
) -> Option<String> {
let time = Instant::now();
@@ -133,6 +135,7 @@ async fn is_dnsbl(
.iter()
.map(|ip| trc::Value::from(ip.to_string()))
.collect::<Vec<_>>(),
Details = element.as_str(),
Elapsed = time.elapsed()
);
@@ -159,6 +162,7 @@ async fn is_dnsbl(
Spam(SpamEvent::Dnsbl),
Hostname = zone.clone(),
Result = trc::Value::None,
Details = element.as_str(),
Elapsed = time.elapsed()
);
@@ -175,6 +179,7 @@ async fn is_dnsbl(
Spam(SpamEvent::DnsblError),
Hostname = zone,
Elapsed = time.elapsed(),
Details = element.as_str(),
CausedBy = err.to_string()
);

View File

@@ -10,7 +10,7 @@ use crate::{Email, Hostname};
impl Hostname {
pub fn new(host: &str) -> Self {
let mut fqdn = host.to_lowercase();
let mut fqdn = host.trim_end_matches('.').to_lowercase();
// Decode punycode
if fqdn.contains("xn--") {
@@ -42,12 +42,20 @@ impl Hostname {
.ok();
Hostname {
ip,
sld: if ip.is_none() {
psl::domain_str(&fqdn).map(str::to_string)
psl::domain(fqdn.as_bytes()).and_then(|domain| {
if domain.suffix().typ().is_some() {
std::str::from_utf8(domain.as_bytes())
.ok()
.map(str::to_string)
} else {
None
}
})
} else {
None
},
ip,
fqdn,
}
}

View File

@@ -380,7 +380,10 @@ pub fn sanitize_email(email: &str) -> Option<String> {
}
}
if found_domain && last_ch != '.' && psl::domain(result.as_bytes()).is_some() {
if found_domain
&& last_ch != '.'
&& psl::domain(result.as_bytes()).is_some_and(|d| d.suffix().typ().is_some())
{
Some(result)
} else {
None