“ An unauthenticated malicious user can use a path traversal vulnerability to read arbitrary files on the server when an attachment exists in a public project nested within at least five groups. “
# This should either# - send the file directly# - or redirect to its URL#defshowreturn render_404 unless uploader&.exists?
ttl, directives = *cache_settings
ttl ||= 0
directives ||= { private:true, must_revalidate:true }
expires_in ttl, directives
file_uploader = [uploader, *uploader.versions.values].find do|version|
version.filename == params[:filename]
endreturn render_404 unless file_uploader
workhorse_set_content_type!
send_upload(file_uploader, attachment: file_uploader.filename, disposition: content_disposition)
end
defsend_upload(file_upload, send_params: {}, redirect_params: {}, attachment:nil, proxy:false, disposition:'attachment')
content_type = content_type_for(attachment)
if attachment
response_disposition = ActionDispatch::Http::ContentDisposition.format(disposition: disposition, filename: attachment)
# Response-Content-Type will not override an existing Content-Type in# Google Cloud Storage, so the metadata needs to be cleared on GCS for# this to work. However, this override works with AWS.
redirect_params[:query] = { "response-content-disposition" => response_disposition,
"response-content-type" => content_type }
# By default, Rails will send uploads with an extension of .js with a# content-type of text/javascript, which will trigger Rails'# cross-origin JavaScript protection.
send_params[:content_type] = 'text/plain'if File.extname(attachment) == '.js'
send_params.merge!(filename: attachment, disposition: disposition)
endif image_scaling_request?(file_upload)
location = file_upload.file_storage? ? file_upload.path : file_upload.url
headers.store(*Gitlab::Workhorse.send_scaled_image(location, params[:width].to_i, content_type))
head :okelsif file_upload.file_storage?
send_file file_upload.path, send_params
elsif file_upload.class.proxy_download_enabled? || proxy
headers.store(*Gitlab::Workhorse.send_url(file_upload.url(**redirect_params)))
head :okelse
redirect_to cdn_fronted_url(file_upload, redirect_params)
endend