Compare commits

...

4 commits

Author SHA1 Message Date
nexy7574
d4049a79bf
feat(policy-server): Prevent local events that fail the policy check
Some checks failed
Checks / Prefligit / prefligit (push) Failing after 1s
Release Docker Image / define-variables (push) Failing after 1s
Release Docker Image / build-image (linux/amd64, release, linux-amd64, base) (push) Has been skipped
Release Docker Image / build-image (linux/arm64, release, linux-arm64, base) (push) Has been skipped
Release Docker Image / merge (push) Has been skipped
Checks / Rust / Format (push) Failing after 1s
Checks / Rust / Clippy (push) Failing after 12s
Checks / Rust / Cargo Test (push) Failing after 15s
2025-07-19 21:09:23 +01:00
nexy7574
1bc06fcd57
feat(policy-server): Soft-fail redactions for failed events 2025-07-19 20:54:06 +01:00
nexy7574
cff4076fad
style(policy-server): Restructure logging 2025-07-19 20:50:47 +01:00
nexy7574
dded3a2981
fix(policy-server): Avoid unnecessary database lookup 2025-07-19 20:47:02 +01:00
3 changed files with 41 additions and 16 deletions

View file

@ -26,20 +26,11 @@ pub async fn policyserv_check(&self, pdu: &PduEvent, room_id: &RoomId) -> Result
return Ok(());
},
};
// TODO: dont do *this*
let pdu_json = self.services.timeline.get_pdu_json(pdu.event_id()).await?;
let outgoing = self
.services
.sending
.convert_to_outgoing_federation_event(pdu_json)
.convert_to_outgoing_federation_event(pdu.to_canonical_object())
.await;
// let s = match serde_json::to_string(outgoing.as_ref()) {
// | Ok(s) => s,
// | Err(e) => {
// warn!("Failed to convert pdu {} to outgoing federation event: {e}",
// pdu.event_id()); return Err!(Request(InvalidParam("Failed to convert PDU
// to outgoing event."))); },
// };
debug!("Checking pdu {outgoing:?} for spam with policy server {via} for room {room_id}");
let response = self
.services
@ -52,14 +43,21 @@ pub async fn policyserv_check(&self, pdu: &PduEvent, room_id: &RoomId) -> Result
let response = match response {
| Ok(response) => response,
| Err(e) => {
warn!("Failed to contact policy server {via} for room {room_id}: {e}");
warn!(
via = %via,
event_id = %pdu.event_id(),
room_id = %room_id,
"Failed to contact policy server: {e}"
);
return Ok(());
},
};
if response.recommendation == "spam" {
warn!(
"Event {} in room {room_id} was marked as spam by policy server {via}",
pdu.event_id().to_owned()
via = %via,
event_id = %pdu.event_id(),
room_id = %room_id,
"Event was marked as spam by policy server",
);
return Err!(Request(Forbidden("Event was marked as spam by policy server")));
}

View file

@ -222,9 +222,7 @@ where
}
// 14-pre. If the event is not a state event, ask the policy server about it
if incoming_pdu.state_key.is_none()
&& incoming_pdu.sender().server_name() != self.services.globals.server_name()
{
if incoming_pdu.state_key.is_none() {
debug!("Checking policy server for event {}", incoming_pdu.event_id);
let policy = self.policyserv_check(&incoming_pdu, room_id);
if let Err(e) = policy.await {
@ -236,6 +234,24 @@ where
debug!("Policy server check passed for event {}", incoming_pdu.event_id);
}
// Additionally, if this is a redaction for a soft-failed event, we soft-fail it
// also
if let Some(redact_id) = incoming_pdu.redacts_id(&room_version_id) {
debug!("Checking if redaction {} is for a soft-failed event", redact_id);
if self
.services
.pdu_metadata
.is_event_soft_failed(&redact_id)
.await
{
warn!(
"Redaction {} is for a soft-failed event, soft failing the redaction",
redact_id
);
soft_fail = true;
}
}
// 14. Check if the event passes auth based on the "current state" of the room,
// if not soft fail it
if soft_fail {

View file

@ -165,6 +165,17 @@ pub async fn create_hash_and_sign_event(
return Err!(Request(Forbidden("Event is not authorized.")));
}
// Check with the policy server
if self
.services
.event_handler
.policyserv_check(&pdu, room_id)
.await
.is_err()
{
return Err!(Request(Forbidden(debug_warn!("Policy server marked this event as spam"))));
}
// Hash and sign
let mut pdu_json = utils::to_canonical_object(&pdu).map_err(|e| {
err!(Request(BadJson(warn!("Failed to convert PDU to canonical JSON: {e}"))))