Merge branch 'svg-xss-fix' into 'security'
Fix for XSS vulnerability in SVG attachments See https://dev.gitlab.org/gitlab/gitlabhq/merge_requests/2059
This commit is contained in:
parent
7e1f7a02db
commit
dd944bf14f
5 changed files with 40 additions and 3 deletions
|
@ -36,7 +36,7 @@ class FileUploader < GitlabUploader
|
|||
escaped_filename = filename.gsub("]", "\\]")
|
||||
|
||||
markdown = "[#{escaped_filename}](#{self.secure_url})"
|
||||
markdown.prepend("!") if image_or_video?
|
||||
markdown.prepend("!") if image_or_video? || dangerous?
|
||||
|
||||
{
|
||||
alt: filename,
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
# Extra methods for uploader
|
||||
module UploaderHelper
|
||||
IMAGE_EXT = %w[png jpg jpeg gif bmp tiff svg]
|
||||
IMAGE_EXT = %w[png jpg jpeg gif bmp tiff]
|
||||
# We recommend using the .mp4 format over .mov. Videos in .mov format can
|
||||
# still be used but you really need to make sure they are served with the
|
||||
# proper MIME type video/mp4 and not video/quicktime or your videos won't play
|
||||
# on IE >= 9.
|
||||
# http://archive.sublimevideo.info/20150912/docs.sublimevideo.net/troubleshooting.html
|
||||
VIDEO_EXT = %w[mp4 m4v mov webm ogv]
|
||||
# These extension types can contain dangerous code and should only be embedded inline with
|
||||
# proper filtering. They should always be tagged as "Content-Disposition: attachment", not "inline".
|
||||
DANGEROUS_EXT = %w[svg]
|
||||
|
||||
def image?
|
||||
extension_match?(IMAGE_EXT)
|
||||
|
@ -20,6 +23,10 @@ module UploaderHelper
|
|||
image? || video?
|
||||
end
|
||||
|
||||
def dangerous?
|
||||
extension_match?(DANGEROUS_EXT)
|
||||
end
|
||||
|
||||
def extension_match?(extensions)
|
||||
return false unless file
|
||||
|
||||
|
|
4
changelogs/unreleased/fix-xss-svg.yml
Normal file
4
changelogs/unreleased/fix-xss-svg.yml
Normal file
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Fix XSS vulnerability in SVG attachments
|
||||
merge_request:
|
||||
author:
|
|
@ -4,6 +4,28 @@ describe UploadsController do
|
|||
let!(:user) { create(:user, avatar: fixture_file_upload(Rails.root + "spec/fixtures/dk.png", "image/png")) }
|
||||
|
||||
describe "GET show" do
|
||||
context 'Content-Disposition security measures' do
|
||||
let(:project) { create(:empty_project, :public) }
|
||||
|
||||
context 'for PNG files' do
|
||||
it 'returns Content-Disposition: inline' do
|
||||
note = create(:note, :with_attachment, project: project)
|
||||
get :show, model: 'note', mounted_as: 'attachment', id: note.id, filename: 'image.png'
|
||||
|
||||
expect(response['Content-Disposition']).to start_with('inline;')
|
||||
end
|
||||
end
|
||||
|
||||
context 'for SVG files' do
|
||||
it 'returns Content-Disposition: attachment' do
|
||||
note = create(:note, :with_svg_attachment, project: project)
|
||||
get :show, model: 'note', mounted_as: 'attachment', id: note.id, filename: 'image.svg'
|
||||
|
||||
expect(response['Content-Disposition']).to start_with('attachment;')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when viewing a user avatar" do
|
||||
context "when signed in" do
|
||||
before do
|
||||
|
|
|
@ -97,7 +97,11 @@ FactoryGirl.define do
|
|||
end
|
||||
|
||||
trait :with_attachment do
|
||||
attachment { fixture_file_upload(Rails.root + "spec/fixtures/dk.png", "`/png") }
|
||||
attachment { fixture_file_upload(Rails.root + "spec/fixtures/dk.png", "image/png") }
|
||||
end
|
||||
|
||||
trait :with_svg_attachment do
|
||||
attachment { fixture_file_upload(Rails.root + "spec/fixtures/unsanitized.svg", "image/svg+xml") }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue