diff --git a/app/controllers/api/attachments_controller.rb b/app/controllers/api/attachments_controller.rb index 5051cfeb..dc99668b 100644 --- a/app/controllers/api/attachments_controller.rb +++ b/app/controllers/api/attachments_controller.rb @@ -34,6 +34,8 @@ module Api end render json: attachment.as_json(only: %i[uuid created_at], methods: %i[url filename content_type]) + rescue Submitters::MaliciousFileExtension => e + render json: { error: e.message }, status: :unprocessable_entity end def build_new_cookie_signatures_json(submitter, attachment) diff --git a/app/javascript/submission_form/dropzone.vue b/app/javascript/submission_form/dropzone.vue index 89e01b3b..275b0f30 100644 --- a/app/javascript/submission_form/dropzone.vue +++ b/app/javascript/submission_form/dropzone.vue @@ -163,12 +163,20 @@ export default { return fetch(this.baseUrl + '/api/attachments', { method: 'POST', body: formData - }).then(resp => resp.json()).then((data) => { - return data + }).then(async (resp) => { + const data = await resp.json() + + if (resp.status === 422) { + alert(data.error) + } else { + return data + } }) } })).then((result) => { - this.$emit('upload', result) + if (result && result[0]) { + this.$emit('upload', result) + } }).finally(() => { this.isLoading = false }) diff --git a/lib/submitters.rb b/lib/submitters.rb index 2c08a09f..2738f773 100644 --- a/lib/submitters.rb +++ b/lib/submitters.rb @@ -13,6 +13,17 @@ module Submitters UnableToSendCode = Class.new(StandardError) InvalidOtp = Class.new(StandardError) + MaliciousFileExtension = Class.new(StandardError) + + DANGEROUS_EXTENSIONS = Set.new(%w[ + exe com bat cmd scr pif vbs vbe js jse wsf wsh msi msp + hta cpl jar app deb rpm dmg pkg mpkg dll so dylib sys + inf reg ps1 psm1 psd1 ps1xml psc1 pssc bat cmd vb vba + sh bash zsh fish run out bin elf gadget workflow lnk scf + url desktop application action workflow apk ipa xap appx + appxbundle msix msixbundle diagcab diagpkg cpl msc ocx + drv scr ins isp mst paf prf shb shs slk ws wsc inf1 inf2 + ].freeze) module_function @@ -111,6 +122,12 @@ module Submitters def create_attachment!(submitter, params) blob = if (file = params[:file]) + extension = File.extname(file.original_filename).delete_prefix('.').downcase + + if DANGEROUS_EXTENSIONS.include?(extension) + raise MaliciousFileExtension, "File type '.#{extension}' is not allowed." + end + ActiveStorage::Blob.create_and_upload!(io: file.open, filename: file.original_filename, content_type: file.content_type)