2022-12-12: Twitter DM Videos Are Accessible to Unauthenticated Users

 

@Whitekitty2012 DMing @BKitty2020 an image -- Twitter works very hard to protect this image from access by third parties. 

@Whitekitty2012 DMing @BKitty2020 a video -- unlike the image above, this video has no HTTP protection.

We have created a simple example that demonstrates that while Twitter goes to great lengths to protect images shared in direct messages (DMs), the videos shared in DMs enjoy no such protections (see also: 2022-12-22 update).  Both image and video URLs are named based on hashes and would be difficult if not functionally impossible to guess:  

Image URL: https://ton.twitter.com/i/ton/data/dm/1600870219324465156/1600870190459256832/KM0EBzij.jpg:small

Video URL: https://video.twimg.com/dm_video/1600877027330064385/pl/320x180/Vn4h39llbQ0jfr1D.m3u8?container=fmp4 

However, if the URLs are somehow leaked (e.g., guessing, reverse engineering, brute force, exported through HAR files, intercepted by proxies), twitter.com protects the DM images from unauthorized HTTP access through session-specific cookies, but the DM videos are available for anyone to access with no HTTP protection.  In short, videos in DMs are protected only through their opaque URLs.  

Right clicking on the URL and choosing "Copy as curl" reproduces the HTTP request your browser used to request this image.  

The curl request which duplicates the above browser request returns a 200 OK response:

In the screenshot below, right-clicking on the image URL  and selecting "Copy as curl" allows one to reproduce the request sent by the browser to the server.  The example uses the HTTP cookie from  @Whitekitty2012 and if that session is closed, the URL is no longer accessible:

If a user who is logged in but not part of the DM conversation attempts to access the URL, the server will return a 404.  After the session has ended, the server will eventually not even return an HTTP response for the image; it will just silently fail.  

Even though Twitter DM images have opaque URLs, Twitter works very hard to protect access to image URLs: they are protected by session Cookies and cannot be accessed if the session is not active or if members outside of the conversation attempt to access the URL.  

Twitter DM videos are also opaquely named, but there is no HTTP protection for their URLs.  The screenshots below show the browser dev tools, and right-clicking on the "m3u8" file.  

Right-clicking on the .m3u8 file. 
The same image as above, just scrolled down. 

Right-clicking on the video URL and selecting "Copy as curl" allows us to get the Media Playlist for the Fragmented MP4 file (RFC 8216):


We can convert the relative URLs in the Media Playlist to full URLs and write a small script to grab all the parts and then concatenate them together.  Note that no HTTP Cookies are required.  


We also pushed the .mp4 and .m4s files into the Internet Archive's Wayback Machine using the Save Page Now interface.   Note that most public web archives, the Wayback Machine runs without being logged into Twitter -- this means that the fact that Wayback Machine could archive these video files means they were not protected at all.  Below is a similar script as above, but here we are accessing the Twitter DM video files after we've pushed them into the Wayback Machine:


In summary, Twitter works very hard to protect images shared in DMs, but offers no HTTP protection to videos shared in DMs.  Yes, the URL names are presumably difficult if not impossible to guess, but there could be heretofore unknown mechanisms for an attacker to exfiltrate or reverse engineer these URLs, in which case the videos can be accessed by anyone unauthenticated client on the web.  

We reported this situation to Twitter via HackerOne (#1798935), but the report was triaged and closed.  

A more detailed version of this vulnerability is provided in:

Michael L. Nelson, Twitter DM Videos Are Accessible to Unauthenticated Users, arXiv:2212.05322, 2022.  

--Michael

The shared image, White Kitty (background) and Black Kitty (foreground).


The reported issue; triaged & closed. 

2022-12-22 Update:

Not counting the one we generated for this study, here are approximately 102 video files from Twitter DMs already archived in the Wayback Machine.  The earliest example is from 2016-03-04:

% curl -s "http://web.archive.org/cdx/search/cdx?url=video.twimg.com/dm_video/&matchType=prefix" | awk '{print "https://web.archive.org/web/" $2 "/" $3};' | grep -v "1600877027330064385" | sort -n -k 10 -t "/" -u | grep 2016 | head -1 
https://web.archive.org/web/20160304122159/https://video.twimg.com/dm_video/70284737[redacted].mp4?_=1

Furthermore, we have established that video.twimg.com does not require HTTPS; it will serve files via HTTP (i.e., without TLS):

% curl -I http://video.twimg.com/dm_video/1600877027330064385/vid/0/3000/320x180/l1mZtezfzjRRYziE.m4s

HTTP/1.1 200 OK

Connection: keep-alive

Content-Length: 37919

perf: 7626143928

content-type: video/mp4

cache-control: max-age=604800, must-revalidate

last-modified: Thu, 08 Dec 2022 15:34:40 GMT

x-transaction-id: 4e772788c1fdbf85

timing-allow-origin: https://twitter.com, https://mobile.twitter.com

x-content-type-options: nosniff

strict-transport-security: max-age=631138519

access-control-allow-origin: *

access-control-expose-headers: Content-Length

Accept-Ranges: bytes

Date: Thu, 22 Dec 2022 20:59:53 GMT

X-Served-By: cache-fty21368-FTY, cache-iad-kjyo7100091-IAD

X-Cache: MISS, MISS

x-tw-cdn: FT

Server-Timing: x-cache;desc=MISS, x-tw-cdn;desc=FT


While continued http support is curious, it is not exploitable since twitter.com has a Content-Security-Policy response header with a value of:

% curl -Is https://twitter.com | grep -i Content-Security-Policy

content-security-policy: connect-src 'self' blob: https://*.pscp.tv https://*.video.pscp.tv https://*.twimg.com https://api.twitter.com https://api-stream.twitter.com https://ads-api.twitter.com https://aa.twitter.com https://caps.twitter.com https://pay.twitter.com https://sentry.io https://ton.twitter.com https://twitter.com https://upload.twitter.com https://www.google-analytics.com https://accounts.google.com/gsi/status [deletia]


Attempts to load content from http://video.twimg.com/ (i.e., http and not https) will be blocked as shown in the figure below.

connect-src in Content-Security-Policy will block requests to http://video.twimg.com/ (bottom right).



Comments