Security
Spindle is a Matrix homeserver: network-facing, multi-tenant, and it federates with servers it has never met. This policy inherits the organisation's (tuna-os/.github/SECURITY.md) and adds what a homeserver produces that an installer or an image does not.
Reporting a vulnerabilityβ
Do not open a public issue for a vulnerability.
- Open Security β Report a vulnerability on this repository and describe the affected route or component, a minimal reproduction, the impact, and a suggested fix if you have one.
- If that button is not there, private reporting has not been enabled
on this repository yet (it is an organisation-level setting, tracked in
#307). Open an ordinary issue titled
security contact requestwith no details in it. A maintainer will open a private advisory and add you to it, and the conversation continues there.
The organisation's fallback (a draft advisory in tuna-os/tunaos) needs
write access to that repository, so it is not a route for an outside
reporter; the request issue above is.
What to reportβ
The classes this codebase produces, most likely first. Two of the first have already shipped and were found by reading (#257, #258), which is why #268 exists.
- Authorization bypass. Any room read (timeline, state, members, context, search, media in a room) served to an account that is not a member or that has left; any admin route reachable without the admin flag; history visibility not honoured for a former member.
- Federation. An
X-Matrixrequest accepted with a bad or missing signature; an event accepted whose signature, content hash or sender domain does not check out, or verified against a key outside its validity window; a peer that is not in a room reading or writing it;send_join/send_leaveaccepting an event other than the one we signed. - Cross-account disclosure. One user's account data, devices, keys, to-device messages, receipts, pushers or search hits reaching another.
- Unauthenticated resource exhaustion. A walk or a write whose cost a peer or an unauthenticated client controls without bound: an endpoint missing from the rate limiter, per-user or per-peer state that grows without a cap, a backfill or key fetch a stranger can make us repeat.
- Authentication. Access-token or session handling, the built-in OIDC provider, delegated authentication, appservice namespace escapes, password and registration flows.
- Outbound requests. Anything that reaches an internal address
through URL previews, federated media, key fetches or well-known
discovery despite
netguard.
The organisation's classes (supply chain, CI secrets, container images) apply to this repository's workflows and images as well.
Disclosureβ
We aim to acknowledge a report within 5 business days, as the
organisation's policy says, and to fix on main as fast as the fix can
be made sound. We ask for a coordinated window of up to 90 days from
acknowledgement before details are published, shorter once the fix has
landed.
There are no tagged releases yet (#308), so "fixed in" names a commit on
main, and main is the only supported line: a deployment tracking
anything older is not supported. When releases exist, the advisory will
name the fixed version as well.
Scopeβ
In scope: this repository, the server it builds, the container image and the workflows that build them. Out of scope: the clients and libraries we depend on (Element, ruma, fjall, axum and the rest); report those to their maintainers, and tell us if Spindle's use of them is what makes the problem reachable.
Finding these yourselfβ
scripts/authorization-rule.pyis the CI check that every room read in the route table asks who is asking, and.semgrep/room-authorization.yamlis the shape it looks for.crates/spindle-server/tests/room_read_authorization.rsandroom_route_authorization.rsare the tests that pin the gates; a new bypass should come with a new case there.- #268 is the standing audit of the authorization surface, and the intake counterpart of this document.