relays usually Announce(Create), so the Create is not from them but the announce is, and it gets processed properly. Lemmy does the correct thing: it sends Announce(...activity...), so the "topmost" activity effectively comes from the sending server and can be verified. however aode relay sends activities as-is, without wrapping. so if we receive activities from someone else, it won't match the http signature and we thus can't be sure this wasn't falsified. added an option to directly fetch such cases. it's probably not great, so defaults to OFF
This commit is contained in:
parent
d77197a325
commit
08fdc93d35
2 changed files with 14 additions and 3 deletions
|
@ -139,6 +139,13 @@ pub struct CompatibilityConfig {
|
|||
#[serde_inline_default(true)]
|
||||
/// compatibility with lemmy: avoid showing images twice
|
||||
pub skip_single_attachment_if_image_is_set: bool,
|
||||
|
||||
#[serde_inline_default(false)]
|
||||
/// compatibility with most relays: since they send us other server's activities, we must fetch
|
||||
/// them to verify that they aren't falsified by the relay itself. this is quite expensive, as
|
||||
/// relays send a lot of activities and we effectively end up fetching again all these, so this
|
||||
/// defaults to false
|
||||
pub verify_relayed_activities_by_fetching: bool,
|
||||
}
|
||||
|
||||
#[serde_inline_default::serde_inline_default]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use apb::{Activity, ActivityType, Base};
|
||||
use axum::{extract::{Query, State}, http::StatusCode, Json};
|
||||
use sea_orm::{sea_query::IntoCondition, ActiveValue::{NotSet, Set}, ColumnTrait, EntityTrait, QueryFilter, QueryOrder, QuerySelect};
|
||||
use upub::{model::job::JobType, selector::{RichActivity, RichFillable}, Context};
|
||||
use upub::{model::job::JobType, selector::{RichActivity, RichFillable}, traits::Fetcher, Context};
|
||||
|
||||
use crate::{AuthIdentity, Identity, builders::JsonLD};
|
||||
|
||||
|
@ -41,7 +41,7 @@ pub async fn page(
|
|||
pub async fn post(
|
||||
State(ctx): State<Context>,
|
||||
AuthIdentity(auth): AuthIdentity,
|
||||
Json(activity): Json<serde_json::Value>
|
||||
Json(mut activity): Json<serde_json::Value>
|
||||
) -> crate::ApiResult<StatusCode> {
|
||||
let Identity::Remote { domain, user: uid, .. } = auth else {
|
||||
if matches!(activity.activity_type(), Ok(ActivityType::Delete)) {
|
||||
|
@ -72,8 +72,12 @@ pub async fn post(
|
|||
let server = upub::Context::server(&aid);
|
||||
|
||||
if activity.actor().id()? != uid {
|
||||
if ctx.cfg().compat.verify_relayed_activities_by_fetching {
|
||||
activity = ctx.pull(&activity.id()?).await?.activity()?;
|
||||
} else {
|
||||
return Err(crate::ApiError::forbidden());
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(_internal) = upub::model::activity::Entity::ap_to_internal(&aid, ctx.db()).await? {
|
||||
return Ok(StatusCode::OK); // already processed
|
||||
|
|
Loading…
Add table
Reference in a new issue