matrix-doc/proposals/2702-media-content-disposit...

6.2 KiB

MSC2702: Content-Disposition usage in the media repo

The current specification does not clarify how to treat Content-Disposition on responses to /download and /thumbnail requests. This has led to clients (and most notably, IRC bridges) relying on implementation-specific behaviour for how their uploads will be represented. This reliance has caused issues in the past where a security decision was made to use an attachment disposition on the download endpoint, however this caused an IRC bridge's use of the media repo to break when trying to send large messages: users on the IRC side were forced to download and open a text file instead of seeing it in their browser. Similar problems have occurred in the past with respect to clients using the download endpoint as an "open in browser" button.

This proposal clarifies the exact behaviour and introduces a set of suggestions for servers to follow with respect to Content-Disposition.

Context

Headers:

Endpoints affected:

Upload endpoints:

Proposal

For /download:

  • Content-Disposition MUST be returned, and MUST be one of inline or attachment.

    • inline should be used when one of the "safe" content types listed below is being served.
  • When uploads are made with a filename, the Content-Disposition header MUST contain the same filename. Otherwise, filename is excluded from the header.

    • If the media being downloaded is remote, the remote server's filename in the Content-Disposition header is used as the filename instead. When the header is not supplied, or does not supply a filename, the local download response does not include a filename (though does still contain a generated Content-Disposition).

For /thumbnail:

  • Content-Disposition MUST be returned, and MUST be inline (see below).
  • Content-Disposition SHOULD include a server-generated filename. For example, thumbnail.png.

Note that in both endpoints Content-Disposition becomes required, though the legal set of parameters is intentionally different. Specifically, because /thumbnail returns server-generated content, that content is safe to serve inline relative to a given user upload and therefore can be inline. It is however atypical for a client to link to /thumbnail directly, but in the event they do we provide a safe default.

The following content types are considered "safe" for inline usage. For /download, servers SHOULD use attachment if the returned Content-Type is not on the list. For /thumbnail, servers SHOULD only generate thumbnails with a Content-Type listed below.

  • text/css
  • text/plain
  • text/csv
  • application/json
  • application/ld+json
  • image/jpeg
  • image/gif
  • image/png
  • image/apng
  • image/webp
  • image/avif
  • video/mp4
  • video/webm
  • video/ogg
  • video/quicktime
  • audio/mp4
  • audio/webm
  • audio/aac
  • audio/mpeg
  • audio/ogg
  • audio/wave
  • audio/wav
  • audio/x-wav
  • audio/x-pn-wav
  • audio/flac
  • audio/x-flac

Content-Type additionally becomes a required header on responses to both /download and /thumbnail, as Content-Disposition without Content-Type is effectively useless in HTTP. The Content-Type header is the Content-Type supplied by the client during /upload. If no Content-Type was supplied during upload, application/octet-stream is used.

Clients SHOULD NOT rely on servers returning inline rather than attachment on /download. Server implementations might decide out of an abundance of caution that all downloads are responded to with attachment, regardless of content type - clients should not be surprised by this behaviour.

Potential issues

This proposal does not require the usage of inline on /download, making it harder for IRC and similar bridges to rely on "pastebin" behaviour. For example, when a large message is posted on the Matrix side of the bridge, the IRC bridge might upload it as a text file due to limits on the IRC side. Ideally, that text file would be rendered inline by the server. Bridges are encouraged to use "proxy APIs" to serve the text file instead, where they can better control the user experience.

Alternatives

No major alternatives identified.

Security considerations

This MSC fixes a possible Cross-Site Scripting issue in environments with insecure configurations. For example, if a Matrix web client is also hosted on the same domain as the media download URL. This is mitigated by only suggesting inline as a disposition on content types which are not likely to execute code within the browser upon being viewed. A browser may still have further bugs which reveal information, though those issues quickly become impractical for the Matrix specification to mitigate.

No new security issues are identified, and careful consideration was put into inline to ensure an extremely limited set of possible media types.

The allowable content types for inline were inspired by the react-sdk, and extended to include what is present in a related Synapse PR. The react-sdk list of types has been known to be safe for several years now, and the added types in the Synapse PR are not subject to XSS or similar attacks. Note that image/svg, text/javascript, and text/html are explicitly not allowed.

Unstable prefix

This MSC has no particular unstable prefix requirements. Servers are already able to return arbitrary Content-Disposition headers on the affected endpoints.