normalize extension

master^2
Pete Matsyburka 2 days ago
parent 5741bb4db2
commit 24f195c7e5

@ -23,7 +23,7 @@ module Api
blob = ActiveStorage::Blob.find_by!(uuid: blob_uuid) blob = ActiveStorage::Blob.find_by!(uuid: blob_uuid)
if Submitters::DANGEROUS_EXTENSIONS.include?(blob.filename.extension.to_s.downcase) if FilenameUtils.dangerous_extension(blob.filename)
Rollbar.error('Dangerous extension') if defined?(Rollbar) Rollbar.error('Dangerous extension') if defined?(Rollbar)
return head :unprocessable_content return head :unprocessable_content

@ -19,7 +19,7 @@ module Api
return head :not_found unless blob return head :not_found unless blob
if Submitters::DANGEROUS_EXTENSIONS.include?(blob.filename.extension.to_s.downcase) if FilenameUtils.dangerous_extension(blob.filename)
Rollbar.error('Dangerous extension') if defined?(Rollbar) Rollbar.error('Dangerous extension') if defined?(Rollbar)
return head :unprocessable_content return head :unprocessable_content

@ -11,11 +11,9 @@ class UserInitialsController < ApplicationController
return redirect_to settings_profile_index_path, notice: I18n.t('unable_to_save_initials') if file.blank? return redirect_to settings_profile_index_path, notice: I18n.t('unable_to_save_initials') if file.blank?
extension = File.extname(file.original_filename).delete_prefix('.').downcase extension = FilenameUtils.dangerous_extension(file.original_filename)
if Submitters::DANGEROUS_EXTENSIONS.include?(extension) raise Submitters::MaliciousFileExtension, "File type '.#{extension}' is not allowed." if extension
raise Submitters::MaliciousFileExtension, "File type '.#{extension}' is not allowed."
end
blob = ActiveStorage::Blob.create_and_upload!(io: file.open, blob = ActiveStorage::Blob.create_and_upload!(io: file.open,
filename: file.original_filename, filename: file.original_filename,

@ -11,11 +11,9 @@ class UserSignaturesController < ApplicationController
return redirect_to settings_profile_index_path, notice: I18n.t('unable_to_save_signature') if file.blank? return redirect_to settings_profile_index_path, notice: I18n.t('unable_to_save_signature') if file.blank?
extension = File.extname(file.original_filename).delete_prefix('.').downcase extension = FilenameUtils.dangerous_extension(file.original_filename)
if Submitters::DANGEROUS_EXTENSIONS.include?(extension) raise Submitters::MaliciousFileExtension, "File type '.#{extension}' is not allowed." if extension
raise Submitters::MaliciousFileExtension, "File type '.#{extension}' is not allowed."
end
blob = ActiveStorage::Blob.create_and_upload!(io: file.open, blob = ActiveStorage::Blob.create_and_upload!(io: file.open,
filename: file.original_filename, filename: file.original_filename,

@ -0,0 +1,21 @@
# frozen_string_literal: true
module FilenameUtils
DANGEROUS_EXTENSIONS = %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 vb vba
sh bash zsh fish run out bin elf gadget workflow lnk scf
url desktop application action apk ipa xap appx
appxbundle msix msixbundle diagcab diagpkg msc ocx
drv ins isp mst paf prf shb shs slk ws wsc inf1 inf2
].freeze
DANGEROUS_EXTENSIONS_REGEXP = /\.(#{Regexp.union(DANGEROUS_EXTENSIONS).source})\W*\z/i
module_function
def dangerous_extension(filename)
ActiveStorage::Filename.wrap(filename).sanitized[DANGEROUS_EXTENSIONS_REGEXP, 1]&.downcase
end
end

@ -16,16 +16,6 @@ module Submitters
MaliciousFileExtension = Class.new(StandardError) MaliciousFileExtension = Class.new(StandardError)
ParamsError = Class.new(StandardError) ParamsError = 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)
FILES_TTL = 5.minutes FILES_TTL = 5.minutes
module_function module_function
@ -127,11 +117,9 @@ module Submitters
def create_attachment!(submitter, file, metadata: {}) def create_attachment!(submitter, file, metadata: {})
raise ParamsError, 'file param is missing' if file.blank? raise ParamsError, 'file param is missing' if file.blank?
extension = File.extname(file.original_filename).delete_prefix('.').downcase extension = FilenameUtils.dangerous_extension(file.original_filename)
if DANGEROUS_EXTENSIONS.include?(extension) raise MaliciousFileExtension, "File type '.#{extension}' is not allowed." if extension
raise MaliciousFileExtension, "File type '.#{extension}' is not allowed."
end
blob = ActiveStorage::Blob.create_and_upload!(io: file.tap(&:rewind).open, blob = ActiveStorage::Blob.create_and_upload!(io: file.tap(&:rewind).open,
filename: file.original_filename, filename: file.original_filename,

@ -247,7 +247,7 @@ module Submitters
detected_extensions = Marcel::TYPE_EXTS[mime_type].to_a.map(&:downcase) detected_extensions = Marcel::TYPE_EXTS[mime_type].to_a.map(&:downcase)
if detected_extensions.any? { |e| Submitters::DANGEROUS_EXTENSIONS.include?(e) } if detected_extensions.any? { |e| FilenameUtils::DANGEROUS_EXTENSIONS.include?(e) }
raise InvalidDefaultValue, "File type '.#{detected_extensions.first}' is not allowed." raise InvalidDefaultValue, "File type '.#{detected_extensions.first}' is not allowed."
end end
@ -276,11 +276,9 @@ module Submitters
def find_or_create_blob_from_url(account, url) def find_or_create_blob_from_url(account, url)
filename = Addressable::URI.parse(url).path.split('/').last.to_s filename = Addressable::URI.parse(url).path.split('/').last.to_s
extension = File.extname(filename).delete_prefix('.').downcase extension = FilenameUtils.dangerous_extension(filename)
if Submitters::DANGEROUS_EXTENSIONS.include?(extension) raise InvalidDefaultValue, "File type '.#{extension}' is not allowed." if extension
raise InvalidDefaultValue, "File type '.#{extension}' is not allowed."
end
cache_key = [account.id, url].join(':') cache_key = [account.id, url].join(':')
checksum = CHECKSUM_CACHE_STORE.fetch(cache_key) checksum = CHECKSUM_CACHE_STORE.fetch(cache_key)

Loading…
Cancel
Save