Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Protect private/internal video files #5370

Merged
merged 6 commits into from
Oct 24, 2022
Merged

Conversation

Chocobozzz
Copy link
Owner

@Chocobozzz Chocobozzz commented Oct 21, 2022

Prevent nginx and peertube to publicly serve private/internal video files.

  • Put private video files under $streaming-playlists-directory/hls/private and $videos-directory/private
  • The current static routes (/static/streaming-playlists/hls and /static/webseed/) only serve public video files (so no files under the private directory)
  • Introduce static routes that will check rights for private video files (/static/streaming-playlists/hls/private/ and /static/webseed/private/)
    • Check Bearer token from headers or a videoFileToken parameter (see below) to ensure the user has the right to access the video files
    • Use a small cache (10 seconds) to prevent too many DB access to check rights (especially with webtorrent that do many HTTP requests)
  • Introduce a new route to generate a video file token
    • The token can only be used to access static files
    • It has an expiration time (a few hours)
    • It's associated to a specific video
    • It can be injected as a query parameter in the URL (videoFileToken) if you can't inject the OAuth token in the request headers (<video> HTML element, WebTorrent, download link etc)
  • HLS player uses the OAuth token to fetch playlist/video files because we can't inject a custom query param inside the M3U8 playlists dependending on the user
  • WebTorrent uses the videoFileToken query param because the library doesn't allow us to update the HTTP request
  • <video> HTML fallback uses the videoFileToken query param because we can't inject headers in the video request
  • Object storage updates:
    • Updated the yaml config: object_storage.upload_acl is splitted into two settings: object_storage.upload_acl.public for public/unlisted videos and object_storage.upload_acl.private for private/internal videos
    • We can't use pre-signed URLs to publicly serve private objects from object storage since it would require to dynamically update M3U8 playlists and we don't want to use auth cookies so PeerTube will proxify object storage requests of internal/private videos (-> check user rights, do an authenticated object storage request, piping the response to the user)
  • Torrent files and magnet URIs of private/internal videos don't contain a webseed URL anymore since they require authentication. Instead you must inject the webseed manually using the videoFileToken query parameter
  • Use Scaleway object storage for some tests that require ACL checks (our object storage mock server doesn't check them)
  • Added mutex to prevent concurrent update of video files (for example moving video files from the public directory to the private one while the video is transcoded)
  • Add a migration script that moves files and/or update object storage ACL

Some admins may not be happy from this change if their setup rely on public video files, even for private/internal videos. If it's the case please comment, we can imagine settings to disable object storage proxy/static files right checks.

@Chocobozzz Chocobozzz merged commit b3ce360 into develop Oct 24, 2022
@Chocobozzz Chocobozzz deleted the feature/private-videos-nginx branch October 24, 2022 12:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant