From f8708ab22eff66d9dc4420aeaca804252050880d Mon Sep 17 00:00:00 2001 From: Astro Date: Thu, 21 Dec 2023 01:59:44 +0100 Subject: [PATCH] main: validate remote_actor only for Follow and Undo --- src/endpoint.rs | 1 + src/main.rs | 26 ++++++++++++++------------ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/endpoint.rs b/src/endpoint.rs index 48bec16..60114d3 100644 --- a/src/endpoint.rs +++ b/src/endpoint.rs @@ -120,6 +120,7 @@ impl<'a> Endpoint<'a> { let public_key = PublicKey::from_pem(remote_actor.public_key.pem.as_bytes())?; if ! (self.signature.verify(&public_key)?) { + tracing::error!("Cannot verify signature for {}: {:?}", self.remote_actor_uri, self.payload); return Err(Error::SignatureFail(self.remote_actor_uri.clone())); } diff --git a/src/main.rs b/src/main.rs index 1fc594e..8142581 100644 --- a/src/main.rs +++ b/src/main.rs @@ -150,18 +150,6 @@ async fn post_relay( endpoint: endpoint::Endpoint<'_>, target: actor::Actor ) -> Response { - let remote_actor = match endpoint.remote_actor(&state.client, &state.actor_cache, target.key_id(), state.priv_key.clone()).await { - Ok(remote_actor) => remote_actor, - Err(e) => { - track_request("POST", "relay", "bad_actor"); - tracing::error!("post_relay bad actor: {e:?}"); - return ( - StatusCode::BAD_REQUEST, - format!("Bad actor: {:?}", e) - ).into_response(); - } - }; - if let Some((redis, in_topic)) = &state.redis { if let Ok(data) = serde_json::to_vec(&endpoint.payload) { if let Err(e) = redis::Cmd::publish(in_topic.as_ref(), data) @@ -173,6 +161,14 @@ async fn post_relay( } } + let remote_actor = endpoint.remote_actor(&state.client, &state.actor_cache, target.key_id(), state.priv_key.clone()) + .await + .map_err(|e| { + track_request("POST", "relay", "bad_actor"); + tracing::error!("post_relay bad actor: {e:?}"); + e + }); + let action = match serde_json::from_value::>(endpoint.payload.clone()) { Ok(action) => action, Err(e) => { @@ -189,6 +185,9 @@ async fn post_relay( .and_then(|object_type| object_type.as_str().map(std::string::ToString::to_string)); if action.action_type == "Follow" { + let Ok(remote_actor) = remote_actor else { + return (StatusCode::BAD_REQUEST, "Invalid actor").into_response(); + }; let priv_key = state.priv_key.clone(); let client = state.client.clone(); tokio::spawn(async move { @@ -241,6 +240,9 @@ async fn post_relay( "{}" ).into_response() } else if action.action_type == "Undo" && object_type == Some("Follow".to_string()) { + let Ok(remote_actor) = remote_actor else { + return (StatusCode::BAD_REQUEST, "Invalid actor").into_response(); + }; match state.database.del_follow( &remote_actor.id, &target.uri(),