MSC3916: Authentication for media

rav/authentication-for-media
Richard van der Hoff 2 years ago
parent 1676be343d
commit 7606e5367b

@ -0,0 +1,224 @@
# MSC3916: Authentication for media access, and new endpoint names
Currently, access to media in Matrix has a number of problems including the following:
* The only protection for media is the obscurity of the URL, and URLs are
easily leaked (eg accidental sharing, access
logs). [synapse#2150](https://github.com/matrix-org/synapse/issues/2150)
* Anybody (including non-matrix users) can cause a homeserver to copy media
into its local
store. [synapse#2133](https://github.com/matrix-org/synapse/issues/2133)
* When a media event is redacted, the media it used remains visible to all.
[synapse#1263](https://github.com/matrix-org/synapse/issues/1263)
* There is currently no way to delete
media. [matrix-spec#226](https://github.com/matrix-org/matrix-spec/issues/226)
* If a user requests GDPR erasure, their media remains visible to all.
* When all users leave a room, their media is not deleted from the server.
These problems are all difficult to address currently, because access to media
is entirely unauthenticated. The first step for a solution is to require user
authentication. Once that is done, it will be possible to impose authorization
requirements to address the problems mentioned above. (See, for example,
[MSC3911](https://github.com/matrix-org/matrix-spec-proposals/pull/3911) which
builds on top of this MSC.)
This proposal supercedes [MSC1902](https://github.com/matrix-org/matrix-spec-proposals/pull/1902).
## Proposal
1. New endpoints
The existing `/_matrix/media/v3/` endpoints are to be deprecated, and replaced
by new endpoints under the `/_matrix/client` and `/_matrix/federation`
hierarchies.
The table below shows a mapping between old and new endpoint:
| Old | Client-Server | Federation |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| [`GET /_matrix/media/v3/preview_url`](https://spec.matrix.org/v1.4/client-server-api/#get_matrixmediav3preview_url) | `GET /_matrix/client/v1/media/preview_url` | - |
| [`GET /_matrix/media/v3/config`](https://spec.matrix.org/v1.4/client-server-api/#get_matrixmediav3config) | `GET /_matrix/client/v1/media/config` | - |
| [`GET /_matrix/media/v3/download/{serverName}/{mediaId}`](https://spec.matrix.org/v1.4/client-server-api/#get_matrixmediav3downloadservernamemediaid) | `GET /_matrix/client/v1/media/download/{serverName}/{mediaId}` | `GET /_matrix/federation/v1/media/download/{serverName}/{mediaId}` |
| [`GET /_matrix/media/v3/download/{serverName}/{mediaId}/{fileName}`](https://spec.matrix.org/v1.4/client-server-api/#get_matrixmediav3downloadservernamemediaidfilename) | `GET /_matrix/client/v1/media/download/{serverName}/{mediaId}/{fileName}` | - |
| [`GET /_matrix/media/v3/thumbnail/{serverName}/{mediaId}`](https://spec.matrix.org/v1.4/client-server-api/#get_matrixmediav3thumbnailservernamemediaid) | `GET /_matrix/client/v1/media/thumbnail/{serverName}/{mediaId}` | `GET /_matrix/federation/v1/media/thumbnail/{serverName}/{mediaId}` |
**Note**: [`POST /_matrix/media/v3/upload`](https://spec.matrix.org/v1.4/client-server-api/#post_matrixmediav3upload)
is **not** modified by this MSC: it is intended that it be brought into line with the other
endpoints by a future MSC, such as [[MSC3911](https://github.com/matrix-org/matrix-spec-proposals/pull/3911).
2. Removal of `allow_remote` parameter from `/download`
The current `/download` and `/thumbnail` enpoints take an `allow_remote`
query parameter, indicating whether the server should request remote media
from other servers. This is redundant with the new endpoints, so will not be
supported.
Servers should never return remote media from `GET
/_matrix/federation/v1/media/download` or `GET
/_matrix/federation/v1/media/thumbnail`; indeed, the `serverName` is
included in the URI only for consistency with the CS-API.
`/_matrix/client/v1/media/download/` and
`/_matrix/client/v1/media/thumnbnail` should return remote media as normal.
3. Authentication on all endpoints
Currently, the `/download` and `/thumbnail` endpoints have no authentication
requirements. Under this proposal, the new endpoints will be authenticated
the same way as other endpoints: they will require an `Authorization` header
which must be `Bearer {accessToken}` for `/_matrix/client`, or the signature
for `/_matrix/federation`.
4. Updated response format
* For the new `/_matrix/client` endpoints, the response format is the same as
the corresponding original endpoints.
* To enable future expansion, for the new `/_matrix/federation` endpoints,
the response is
[`multipart/mixed`](https://www.w3.org/Protocols/rfc1341/7_2_Multipart.html)
content with two parts: the first must be a JSON object (and should have a
`Content-type: application/json` header), and the second is the media item
as per the original endpoints.
No properties are yet specified for the JSON object to be returned.
An example response:
```
Content-Type: multipart/mixed; boundary=gc0p4Jq0M2Yt08jU534c0p
--gc0p4Jq0M2Yt08jU534c0p
Content-Type: application/json
{}
--gc0p4Jq0M2Yt08jU534c0p
Content-Type: text/plain
This media is plain text. Maybe somebody used it as a paste bin.
--gc0p4Jq0M2Yt08jU534c0p
```
5. Backwards compatibility mechanisms
a. Backwards compatibility with older servers: if a client or requesting
server receives a 404 error with a non-JSON response, or a 400 or 404 error with
`{"errcode": "M_UNRECOGNIZED"}`, in response to a request to one of the new
endpoints, they may retry the request using the original endpoint.
b. Backwards compatibility with older clients and federating servers:
servers may for a short time choose to allow unauthenticated access via the
deprecated endpoints.
### Effects on client applications
Naturally, implementations will be required to provide `Authorization` headers
when accessing the new endpoints. This will be simple in some cases, but rather
more involved in others. This section considers some of those cases.
#### IRC/XMPP bridges
Possibly the largest impact will be on IRC and XMPP bridges. Since IRC and
XMPP have no media repository of their own, these bridges currently transform
`mxc:` URIs into `https://<server>/_matrix/media/v3/download/` URIs and forward
those links to the remote platform. This will no longer be a viable option.
One potential solution is for the bridges to provide a proxy.
In this scenario, the bridge would have a secret HMAC key. When it
receives a matrix event referencing a piece of media, it should create a new URI
referencing the media, include an HMAC to prevent tampering. For example:
```
https://<bridge_server>/media/{originServerName}/{mediaId}?mac={hmac}
```
When the bridge later receives a request to that URI, it checks the hmac,
and proxies the request to the homeserver, using its AS access
token in the `Authorization` header.
The bridge might also choose to embed information such as the room that
referenced the media, and the time that the link was generated, in the URL.
Such mechanisms would allow the bridge to impose controls such as:
* Limiting the time a media link is valid for. Doing so would help prevent
visibility to users who weren't participating in the chat.
* Rate-limiting the amount of media being shared in a particular room (in other
words, avoiding the use of Matrix as a Warez distribution system).
#### Icons for "social login" flows
When a server supports multiple login providers, it provides the client with
icons for the login providers as `mxc:` media URIs. These must be accessible
without authentication (because the client has no access token at the time the
icons are displayed).
This remains a somewhat unsolved problem. Possibly the clients can continue
to call the legacy `/_matrix/media/v3/download` URI for now: ultimately this
problem will be solved by the transition to OIDC. Alternatively, we may need
to provide an alternative `/_matrix/client/v3/login/sso/icon/{idpId}` API
specifically for access to these icon.
(This was previously discussed in
[MSC2858](https://github.com/matrix-org/matrix-spec-proposals/pull/2858#discussion_r543513811).)
## Potential issues
* Setting the `Authorization` header is going to be annoying for web clients. Service workers
might be needed.
* Users will be unable to copy links to media from web clients to share out of
band. This is considered a feature, not a bug.
## Alternatives
* Allow clients to upload media which does not require authentication (for
example via a `public=true` query parameter). This might be particularly
useful for IRC/XMPP bridges, which could upload any media they encounter to
the homeserver's repository.
The danger with this is that is that there's little stopping clients
continuing to upload media as "public", negating all of the benefits in this
MSC. It might be ok if media upload it was restricted to certain privileged
users.
* We could simply require that `Authorization` headers be given when calling
the existing endpoints. However, doing so would make it harder to evaluate
the proportion of clients which have been updated, and it is a good
opportunity to bring these endpoints into line with the rest of the
client-server and federation APIs.
* There's no real need to rename `GET /_matrix/media/v3/preview_url` and `GET
/_matrix/media/v3/config` at present, and we could just leave them in
place. However, changing them at the same time makes the API more consistent.
Conversely, we should make sure to rename `POST
/_matrix/media/v3/upload`. The reason to delay doing so is because MSC3911
will make more substantial changes to this endpoint, requiring another
rename, and it is expected that both proposals will be mergeed at the same
time (so a double rename will be confusing and unnecessary). However, if
MSC3911 is delayed or rejected, we should reconsider this.
* Rather than messing with multipart content, have a separate endpoint for
servers to get the metadata for a media item. That would mean two requests,
but might make more sense than both `/thumbnail` and `/download` providing
the info.
## Unstable prefix
While this proposal is in development, the new endpoints should be named as follows:
* GET /_matrix/client/unstable/org.matrix.msc3916/media/preview_url
* GET /_matrix/client/unstable/org.matrix.msc3916/media/config
* GET /_matrix/client/unstable/org.matrix.msc3916/media/download/{serverName}/{mediaId}
* GET /_matrix/client/unstable/org.matrix.msc3916/media/download/{serverName}/{mediaId}/{fileName}
* GET /_matrix/client/unstable/org.matrix.msc3916/media/thumbnail/{serverName}/{mediaId}
* GET /_matrix/federation/unstable/org.matrix.msc3916/media/download/{serverName}/{mediaId}
* GET /_matrix/federation/unstable/org.matrix.msc3916/media/thumbnail/{serverName}/{mediaId}
## Dependencies
None at present.
Loading…
Cancel
Save