Add verify_is_remote_object

This commit is contained in:
Felix Ableitner 2025-01-15 12:00:52 +01:00
parent 43b51d79ce
commit 095d0aee2d

View file

@ -1,6 +1,7 @@
//! Verify that received data is valid
use crate::error::Error;
use crate::{config::Data, error::Error, fetch::object_id::ObjectId, traits::Object};
use serde::Deserialize;
use url::Url;
/// Check that both urls have the same domain. If not, return UrlVerificationError.
@ -36,3 +37,32 @@ pub fn verify_urls_match(a: &Url, b: &Url) -> Result<(), Error> {
}
Ok(())
}
/// Check that the given ID doesn't match the local domain.
///
/// It is important to verify this to avoid local objects from being overwritten. In general
/// locally created objects should be considered authorative, while incoming federated data
/// is untrusted. Lack of such a check could allow an attacker to rewrite local posts. It could
/// also result in an `object.local` field being overwritten with `false` for local objects, resulting in invalid data.
///
/// ```
/// # use url::Url;
/// # use activitypub_federation::protocol::verification::verify_is_remote_object;
/// let a = Url::parse("https://example.com/u/name")?;
/// assert!(verify_is_remote_object(&a, &b).is_ok());
/// # Ok::<(), url::ParseError>(())
/// ```
pub fn verify_is_remote_object<Kind, R: Clone>(
id: &ObjectId<Kind>,
data: &Data<<Kind as Object>::DataType>,
) -> Result<(), Error>
where
Kind: Object<DataType = R> + Send + 'static,
for<'de2> <Kind as Object>::Kind: Deserialize<'de2>,
{
if id.is_local(data) {
Err(Error::UrlVerificationError("Object is not remote"))
} else {
Ok(())
}
}