mirror of
https://gitlab.com/famedly/conduit.git
synced 2025-04-22 14:10:16 +03:00
Do spamhaus check
This commit is contained in:
parent
b76357c80e
commit
7dd9bda17b
2 changed files with 26 additions and 4 deletions
|
@ -7,6 +7,7 @@ use crate::{
|
|||
service::media::{FileMeta, UrlPreviewData},
|
||||
config::UrlPreviewPermission,
|
||||
services, utils, Error, Result, Ruma};
|
||||
use hickory_resolver::error::ResolveErrorKind;
|
||||
use http::header::{CONTENT_DISPOSITION, CONTENT_TYPE};
|
||||
use ruma::{
|
||||
api::{
|
||||
|
@ -126,7 +127,7 @@ async fn download_html(
|
|||
Ok(data)
|
||||
}
|
||||
|
||||
fn url_request_allowed(addr: &IpAddr) -> bool {
|
||||
fn is_ip_external(addr: &IpAddr) -> bool {
|
||||
// could be implemented with reqwest when it supports IP filtering:
|
||||
// https://github.com/seanmonstar/reqwest/issues/1515
|
||||
|
||||
|
@ -179,18 +180,38 @@ fn url_request_allowed(addr: &IpAddr) -> bool {
|
|||
|
||||
/// Generate URL preview data from the given URL
|
||||
async fn request_url_preview(url: &Url) -> Result<UrlPreviewData> {
|
||||
// resolve host to IP to ensure it's not a local IP (host guaranteed to not be None)
|
||||
// host guaranteed to not be None by get_media_preview_route
|
||||
let host = url.host_str().unwrap();
|
||||
|
||||
// resolve host to IP to ensure it's not an internal IP
|
||||
let dns_resolver = services().globals.dns_resolver();
|
||||
match dns_resolver.lookup_ip(url.host_str().unwrap()).await {
|
||||
match dns_resolver.lookup_ip(host).await {
|
||||
Err(_) => {
|
||||
return Err(Error::BadServerResponse("Failed to resolve media preview host"));
|
||||
},
|
||||
Ok(lookup) if lookup.iter().any(|ip| !url_request_allowed(&ip)) => {
|
||||
Ok(lookup) if lookup.iter().any(|ip| !is_ip_external(&ip)) => {
|
||||
return Err(Error::BadRequest(ErrorKind::Unknown, "Requesting from this address forbidden"));
|
||||
},
|
||||
Ok(_) => { },
|
||||
}
|
||||
|
||||
// Spamhaus API is over DNS. Query the API domain, no result = no block
|
||||
// https://docs.spamhaus.com/datasets/docs/source/70-access-methods/data-query-service/040-dqs-queries.html
|
||||
if services().globals.url_previews().use_spamhaus_denylist {
|
||||
let resolver = services().globals.dns_resolver();
|
||||
match resolver.lookup_ip(format!("{host}.dbl.spamhaus.org")).await {
|
||||
Err(e) => {
|
||||
if let ResolveErrorKind::NoRecordsFound { .. } = e.kind() { }
|
||||
else {
|
||||
tracing::log::warn!("Failed to check Spamhaus denylist: {}", e);
|
||||
}
|
||||
},
|
||||
Ok(_) => {
|
||||
return Err(Error::BadRequest(ErrorKind::Unknown, "Domain fails reputation check"));
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
let client = services().globals.default_client();
|
||||
let response = client.head(url.as_str()).send().await?;
|
||||
|
||||
|
|
|
@ -110,6 +110,7 @@ pub struct WellKnownConfig {
|
|||
pub struct UrlPreviewConfig {
|
||||
pub default: UrlPreviewPermission,
|
||||
pub exceptions: Vec<WildCardedDomain>,
|
||||
pub use_spamhaus_denylist: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Default)]
|
||||
|
|
Loading…
Reference in a new issue