Skip to content

Unauthenticated GET /api/v1/events/ref-updates leaks private-repo ref metadata (REST analog of #112) #114

Description

@beardthelion

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:12list_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

  1. 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.
  2. Restrict the endpoint to the node operator (signature + node-owner check).
  3. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    crate:nodegitlawb-node — the serving node and REST APIkind:securityVulnerability fix or hardeningsev:highMajor break or real security/trust risk, no easy workaroundsubsystem:apiNode REST API request/response surfacesubsystem:visibilityPath-scoped visibility and content withholding

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions