Don't allow access to arbitrary media tracks by ID

This resolves an issue raised via Bugcrowd that allows a user who has
access to a MediaObject to retrieve any MediaTrack by ID, not just
MediaTracks belonging to the MediaObject specified in the path.

flag=none

test plan:
- create a media object (ID 1)
- create another media object (ID 2)
- create a track on the second media object (ID 1)
- attempt to access it by GETing `/media_objects/1/media_tracks/1`
  - expect to receive a 404
- attempt to access it by GETing `/media_objects/2/media_tracks/1`
  - expect to receive a 200

Change-Id: I5e846b41a2731771a6a477df91cec13666080be5
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/318351
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
QA-Review: Isaac Moore <isaac.moore@instructure.com>
Reviewed-by: Ed Schiebel <eschiebel@instructure.com>
Reviewed-by: Cody Cutrer <cody@instructure.com>
Product-Review: Isaac Moore <isaac.moore@instructure.com>
This commit is contained in:
Isaac Moore 2023-05-17 00:19:42 -05:00
parent 5a861ca0d9
commit e4ffbd54ee
2 changed files with 10 additions and 1 deletions

View File

@ -127,7 +127,8 @@ class MediaTracksController < ApplicationController
# -H 'Authorization: Bearer <token>'
#
def show
@media_track = MediaTrack.find params[:id]
@media_object = MediaObject.active.by_media_id(params[:media_object_id]).first
@media_track = @media_object.media_tracks.find(params[:id])
@media_track.validate! # in case this somehow got saved to the database in the xss-vulnerable TTML format
if stale? etag: @media_track, last_modified: @media_track.updated_at.utc
render plain: @media_track.webvtt_content

View File

@ -91,6 +91,14 @@ describe MediaTracksController do
get "show", params: { media_object_id: @mo.media_id, id: track.id }
expect(response).to have_http_status(:unprocessable_entity)
end
it "does not show tracks that belong to a different media object" do
mo2 = factory_with_protected_attributes(MediaObject, media_id: "0_abcdefghi", old_media_id: "1_012345678", context: @course)
track = mo2.media_tracks.create!(kind: "subtitles", locale: "en", content: "blah")
get "show", params: { media_object_id: @mo.media_id, id: track.id }
expect(response).to have_http_status(:not_found)
end
end
describe "#destroy" do