|
| 1 | +URL Previews |
| 2 | +============ |
| 3 | + |
| 4 | +Design notes on a URL previewing service for Matrix: |
| 5 | + |
| 6 | +Options are: |
| 7 | + |
| 8 | + 1. Have an AS which listens for URLs, downloads them, and inserts an event that describes their metadata. |
| 9 | + * Pros: |
| 10 | + * Decouples the implementation entirely from Synapse. |
| 11 | + * Uses existing Matrix events & content repo to store the metadata. |
| 12 | + * Cons: |
| 13 | + * Which AS should provide this service for a room, and why should you trust it? |
| 14 | + * Doesn't work well with E2E; you'd have to cut the AS into every room |
| 15 | + * the AS would end up subscribing to every room anyway. |
| 16 | + |
| 17 | + 2. Have a generic preview API (nothing to do with Matrix) that provides a previewing service: |
| 18 | + * Pros: |
| 19 | + * Simple and flexible; can be used by any clients at any point |
| 20 | + * Cons: |
| 21 | + * If each HS provides one of these independently, all the HSes in a room may needlessly DoS the target URI |
| 22 | + * We need somewhere to store the URL metadata rather than just using Matrix itself |
| 23 | + * We can't piggyback on matrix to distribute the metadata between HSes. |
| 24 | + |
| 25 | + 3. Make the synapse of the sending user responsible for spidering the URL and inserting an event asynchronously which describes the metadata. |
| 26 | + * Pros: |
| 27 | + * Works transparently for all clients |
| 28 | + * Piggy-backs nicely on using Matrix for distributing the metadata. |
| 29 | + * No confusion as to which AS |
| 30 | + * Cons: |
| 31 | + * Doesn't work with E2E |
| 32 | + * We might want to decouple the implementation of the spider from the HS, given spider behaviour can be quite complicated and evolve much more rapidly than the HS. It's more like a bot than a core part of the server. |
| 33 | + |
| 34 | + 4. Make the sending client use the preview API and insert the event itself when successful. |
| 35 | + * Pros: |
| 36 | + * Works well with E2E |
| 37 | + * No custom server functionality |
| 38 | + * Lets the client customise the preview that they send (like on FB) |
| 39 | + * Cons: |
| 40 | + * Entirely specific to the sending client, whereas it'd be nice if /any/ URL was correctly previewed if clients support it. |
| 41 | + |
| 42 | + 5. Have the option of specifying a shared (centralised) previewing service used by a room, to avoid all the different HSes in the room DoSing the target. |
| 43 | + |
| 44 | +Best solution is probably a combination of both 2 and 4. |
| 45 | + * Sending clients do their best to create and send a preview at the point of sending the message, perhaps delaying the message until the preview is computed? (This also lets the user validate the preview before sending) |
| 46 | + * Receiving clients have the option of going and creating their own preview if one doesn't arrive soon enough (or if the original sender didn't create one) |
| 47 | + |
| 48 | +This is a bit magical though in that the preview could come from two entirely different sources - the sending HS or your local one. However, this can always be exposed to users: "Generate your own URL previews if none are available?" |
| 49 | + |
| 50 | +This is tantamount also to senders calculating their own thumbnails for sending in advance of the main content - we are trusting the sender not to lie about the content in the thumbnail. Whereas currently thumbnails are calculated by the receiving homeserver to avoid this attack. |
| 51 | + |
| 52 | +However, this kind of phishing attack does exist whether we let senders pick their thumbnails or not, in that a malicious sender can send normal text messages around the attachment claiming it to be legitimate. We could rely on (future) reputation/abuse management to punish users who phish (be it with bogus metadata or bogus descriptions). Bogus metadata is particularly bad though, especially if it's avoidable. |
| 53 | + |
| 54 | +As a first cut, let's do #2 and have the receiver hit the API to calculate its own previews (as it does currently for image thumbnails). We can then extend/optimise this to option 4 as a special extra if needed. |
| 55 | + |
| 56 | +API |
| 57 | +--- |
| 58 | + |
| 59 | +``` |
| 60 | +GET /_matrix/media/r0/preview_url?url=http://wherever.com |
| 61 | +200 OK |
| 62 | +{ |
| 63 | + "og:type" : "article" |
| 64 | + "og:url" : "https://twitter.com/matrixdotorg/status/684074366691356672" |
| 65 | + "og:title" : "Matrix on Twitter" |
| 66 | + "og:image" : "https://pbs.twimg.com/profile_images/500400952029888512/yI0qtFi7_400x400.png" |
| 67 | + "og:description" : "“Synapse 0.12 is out! Lots of polishing, performance & bugfixes: /sync API, /r0 prefix, fulltext search, 3PID invites https://t.co/5alhXLLEGP”" |
| 68 | + "og:site_name" : "Twitter" |
| 69 | +} |
| 70 | +``` |
| 71 | + |
| 72 | +* Downloads the URL |
| 73 | + * If HTML, just stores it in RAM and parses it for OG meta tags |
| 74 | + * Download any media OG meta tags to the media repo, and refer to them in the OG via mxc:// URIs. |
| 75 | + * If a media filetype we know we can thumbnail: store it on disk, and hand it to the thumbnailer. Generate OG meta tags from the thumbnailer contents. |
| 76 | + * Otherwise, don't bother downloading further. |
0 commit comments