SECURITY: Ensure only image uploads can be inlined

This prevents malicious files (for example special crafted XMLs) to be
used in XSS attacks.
This commit is contained in:
Dan Ungureanu 2019-12-11 15:21:41 +02:00
parent dc6b02f050
commit adfa793731
No known key found for this signature in database
GPG Key ID: 0AA2A00D6ACC8B84
2 changed files with 15 additions and 3 deletions

View File

@ -207,10 +207,10 @@ class UploadsController < ApplicationController
content_type: MiniMime.lookup_by_filename(upload.original_filename)&.content_type content_type: MiniMime.lookup_by_filename(upload.original_filename)&.content_type
} }
if params[:inline] if !FileHelper.is_supported_image?(upload.original_filename)
opts[:disposition] = "inline"
elsif !FileHelper.is_supported_image?(upload.original_filename)
opts[:disposition] = "attachment" opts[:disposition] = "attachment"
elsif params[:inline]
opts[:disposition] = "inline"
end end
file_path = Discourse.store.path_for(upload) file_path = Discourse.store.path_for(upload)

View File

@ -305,6 +305,18 @@ describe UploadsController do
end end
describe "#show_short" do describe "#show_short" do
it 'inlines only supported image files' do
upload = upload_file("smallest.png")
get upload.short_path, params: { inline: true }
expect(response.header['Content-Type']).to eq('image/png')
expect(response.header['Content-Disposition']).to include('inline;')
upload.update!(original_filename: "test.xml")
get upload.short_path, params: { inline: true }
expect(response.header['Content-Type']).to eq('application/xml')
expect(response.header['Content-Disposition']).to include('attachment;')
end
describe "local store" do describe "local store" do
fab!(:image_upload) { upload_file("smallest.png") } fab!(:image_upload) { upload_file("smallest.png") }