Summary
GET /api/v1/events/ref-updates (list_ref_updates, crates/gitlawb-node/src/api/events.rs:12, mounted at crates/gitlawb-node/src/server.rs:325) takes no auth, no repo argument, and no visibility check. It returns ref_name, old_sha, new_sha, pusher_did, node_did, and the repo slug for every row in received_ref_updates across all repos, including private ones, to any anonymous caller.
This is the REST analog of #112 (GraphQL refUpdates). PR #113 closed the per-repo list_repo_events leak for locally-hosted private repos, but it deliberately left this global feed alone to keep that PR scoped to the per-repo surfaces. The per-repo fix does not close this path: an attacker who knows (or guesses) a repo's full owner-DID slug can still read its push history from the global feed.
Where
crates/gitlawb-node/src/api/events.rs:12 — list_ref_updates handler, no auth/visibility gate
crates/gitlawb-node/src/server.rs:325 — route on the optional_signature read group
- the query is
list_ref_updates(limit) with no per-caller filter
Options
- Filter the feed to rows for repos the caller may read (a visibility join on the feed query), deriving any count from the post-filter set.
- Restrict the endpoint to the node operator (signature + node-owner check).
- Decide explicitly that the global gossip feed is intentionally public (federation requires it) and document the threat-model decision plus what data minimization applies.
The same load-bearing assumption sits under the list_repo_events gossip-only (no-local-row) branch: it is only safe to serve publicly if origin nodes' announce-gate keeps private-at-origin repos out of gossip. A misbehaving peer would leak private ref metadata through both this feed and that branch.
Related
Summary
GET /api/v1/events/ref-updates(list_ref_updates,crates/gitlawb-node/src/api/events.rs:12, mounted atcrates/gitlawb-node/src/server.rs:325) takes no auth, no repo argument, and no visibility check. It returnsref_name,old_sha,new_sha,pusher_did,node_did, and the repo slug for every row inreceived_ref_updatesacross all repos, including private ones, to any anonymous caller.This is the REST analog of #112 (GraphQL
refUpdates). PR #113 closed the per-repolist_repo_eventsleak for locally-hosted private repos, but it deliberately left this global feed alone to keep that PR scoped to the per-repo surfaces. The per-repo fix does not close this path: an attacker who knows (or guesses) a repo's full owner-DID slug can still read its push history from the global feed.Where
crates/gitlawb-node/src/api/events.rs:12—list_ref_updateshandler, no auth/visibility gatecrates/gitlawb-node/src/server.rs:325— route on theoptional_signatureread grouplist_ref_updates(limit)with no per-caller filterOptions
The same load-bearing assumption sits under the
list_repo_eventsgossip-only (no-local-row) branch: it is only safe to serve publicly if origin nodes' announce-gate keeps private-at-origin repos out of gossip. A misbehaving peer would leak private ref metadata through both this feed and that branch.Related
refUpdates, same leak class)list_repo_eventsgate that this complements)