domain: webmention verify job does not re-check post visibility before persisting #60

Open
opened 2026-07-03 01:42:22 +00:00 by rosa · 1 comment
Owner

Found during a code review of the domain crate.

Location: crates/domain/src/services.rs:1050 (receive-time gate); verify job in crates/infra
Severity: Correctness — ADR-0009 gate bypass

Problem

The public/live gate runs only at receive time; the queued verify job upserts the mention with no post-state re-check, and the upsert SQL guards only against the blocklist. A post unpublished or made private between receive and verify (or during a retry loop) still gets a persisted mention.

Failure scenario

An attacker POSTs a webmention for a public post; the owner unpublishes it before the background verification runs; the job confirms the backlink and persists a mention row for a now-private post.

Suggested fix

Re-check post visibility in the verify job (or in the upsert query) before persisting.

Found during a code review of the `domain` crate. **Location:** `crates/domain/src/services.rs:1050` (receive-time gate); verify job in `crates/infra` **Severity:** Correctness — ADR-0009 gate bypass ## Problem The public/live gate runs only at receive time; the queued verify job upserts the mention with no post-state re-check, and the upsert SQL guards only against the blocklist. A post unpublished or made private between receive and verify (or during a retry loop) still gets a persisted mention. ## Failure scenario An attacker POSTs a webmention for a public post; the owner unpublishes it before the background verification runs; the job confirms the backlink and persists a mention row for a now-private post. ## Suggested fix Re-check post visibility in the verify job (or in the upsert query) before persisting.
Author
Owner

Triage: confirmed. The public/live gate runs only in receive_webmention; verify_received_webmention_job (crates/infra/src/jobs/webmention.rs) upserts on a confirmed backlink with no post-state re-check, so a post unpublished between receive and verify still gets a mention row. Fix: re-check is_publicly_listed (or guard the upsert SQL on post state) before persisting, per ADR-0009.

Triage: confirmed. The public/live gate runs only in `receive_webmention`; `verify_received_webmention_job` (crates/infra/src/jobs/webmention.rs) upserts on a confirmed backlink with no post-state re-check, so a post unpublished between receive and verify still gets a mention row. Fix: re-check `is_publicly_listed` (or guard the upsert SQL on post state) before persisting, per ADR-0009.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
rosa/vernier#60
No description provided.