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. |
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. |
The shared image, White Kitty (background) and Black Kitty (foreground). |
The reported issue; triaged & closed. |
% 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
% 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]
connect-src in Content-Security-Policy will block requests to http://video.twimg.com/ (bottom right). |
Comments
Post a Comment