Index: app/models/attachment.rb =================================================================== --- app/models/attachment.rb (revision 14645) +++ app/models/attachment.rb (working copy) @@ -26,7 +26,7 @@ validates_length_of :filename, :maximum => 255 validates_length_of :disk_filename, :maximum => 255 validates_length_of :description, :maximum => 255 - validate :validate_max_file_size + validate :validate_max_file_size, :validate_file_extension attr_protected :id acts_as_event :title => :filename, @@ -69,6 +69,28 @@ end end + def validate_file_extension + blacklisted = false + ext = File.extname(self.filename) + + # if defined, check whether file's extension is blacklisted + if not Setting.attachment_extension_blacklist.empty? + extension_blacklist = Setting.attachment_extension_blacklist.split(",").map { |s| '.' + s } + if extension_blacklist.include?(ext) + blacklisted = true + errors.add(:base, l(:error_attachment_extension_blacklisted, :blacklist => Setting.attachment_extension_blacklist)) + end + end + + # if defined, check whether file's extension is whitelisted + if (not Setting.attachment_extension_whitelist.empty?) and (not blacklisted) + extension_whitelist = Setting.attachment_extension_whitelist.split(",").map { |s| '.' + s } + if not extension_whitelist.include?(ext) + errors.add(:base, l(:error_attachment_extension_not_whitelisted, :whitelist => Setting.attachment_extension_whitelist)) + end + end + end + def file=(incoming_file) unless incoming_file.nil? @temp_file = incoming_file Index: app/views/settings/_general.html.erb =================================================================== --- app/views/settings/_general.html.erb (revision 14645) +++ app/views/settings/_general.html.erb (working copy) @@ -7,6 +7,10 @@ <%= wikitoolbar_for 'settings_welcome_text' %>

<%= setting_text_field :attachment_max_size, :size => 6 %> <%= l(:"number.human.storage_units.units.kb") %>

+

<%= setting_text_field :attachment_extension_whitelist %> +<%= l(:text_comma_separated) %>

+

<%= setting_text_field :attachment_extension_blacklist %> +<%= l(:text_comma_separated) %>

<%= setting_text_field :per_page_options, :size => 20 %> <%= l(:text_comma_separated) %>

Index: config/locales/en.yml =================================================================== --- config/locales/en.yml (revision 14645) +++ config/locales/en.yml (working copy) @@ -204,6 +204,8 @@ error_unable_delete_issue_status: 'Unable to delete issue status' error_unable_to_connect: "Unable to connect (%{value})" error_attachment_too_big: "This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})" + error_attachment_extension_not_whitelisted: "Attachment extension not whitelisted; allowed extensions: %{whitelist}" + error_attachment_extension_blacklisted: "Attachment extension blacklisted; disallowed extensions: %{blacklist}" error_session_expired: "Your session has expired. Please login again." warning_attachments_not_saved: "%{count} file(s) could not be saved." error_password_expired: "Your password has expired or the administrator requires you to change it." @@ -356,6 +358,8 @@ setting_login_required: Authentication required setting_self_registration: Self-registration setting_attachment_max_size: Maximum attachment size + setting_attachment_extension_whitelist: Whitelisted attachment extensions + setting_attachment_extension_blacklist: Blacklisted attachment extensions setting_issues_export_limit: Issues export limit setting_mail_from: Emission email address setting_bcc_recipients: Blind carbon copy recipients (bcc) Index: config/settings.yml =================================================================== --- config/settings.yml (revision 14645) +++ config/settings.yml (working copy) @@ -55,6 +55,10 @@ attachment_max_size: format: int default: 5120 +attachment_extension_whitelist: + default: +attachment_extension_blacklist: + default: issues_export_limit: format: int default: 500