|
|
A registered peer was trusted with more than "advertise your own
public groups":
- `receive_directory` set `source_hub` from `body.hub_id`, so a peer
could relay or spoof a third hub's groups into our directory. It is
now bound to the token's verified `iss`. The push is also capped
(500 groups/request, 2000/peer), rows are type- and length-checked,
and a federated id that collides with a local group is refused so it
cannot shadow one.
- `receive_revocation` forwarded the peer's token to local nodes,
which reject a token signed by another hub's key — a silent no-op,
and there is no local node hosting a federated group anyway. It now
verifies the inner token against the sending peer's key and, for
`target == "group"`, prunes our copy of the peer's directory entry
when `source_hub` matches. A peer cannot revoke our users or a group
it did not advertise.
- The state-changing endpoints (`POST /mhp/directory`, `/mhp/revoke`)
now reject a replayed `jti` within the token's TTL. Audience binding
is unavailable — the sending side that would set `aud` is unbuilt —
and this covers the replay concern in its place; the idempotent
`GET /mhp/directory` is not affected.
Third security review, finding M4.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011pG75yGK3NthNfyjH74omG
|