1

I've tried everything now and I can't seem to figure out how to add content type validations in CarrierWave before performing actual processing on files I am uploading. The reason for this is that I want to allow only images but a user can upload a spoofed content file and rename file.pdf file to file.jpg. Steps I have tried so far:

photo_uploader.rb

def content_type_whitelist
    /image\//
end

I have tried validate_integrity in my uploader but no luck as well. I have also tried overwriting CarrierWave error messages (which seems to me strange to me actually):

en:
  errors:
    messages:
      content_type_whitelist: "You are not allowed to upload %{content_type} file"

but I am getting an error from MiniMagic

"Failed to manipulate with MiniMagick, maybe it is not an image? Original Error: %{e}"

The thing is that I want to display rails validations instead so that when the content type is not one of those I have defined in my model it displays the message like "File should be one of image/jpeg, image/png, image/gif". So I need a way to force rails validations to trigger before image processing, although I think it is not quite possible.

Here they say that CarrierWave::Uploader::MagicMimeWhitelist should be included in order to perform mime types validations so I've tried that but got uninitialzied constant CarrierWave::Uploader::MagicMimeWhitelist (server restarted before)

include CarrierWave::Uploader::MagicMimeWhitelist
  def whitelist_mime_type_pattern
    /image\//
  end

I've tried using carrier-mimetype-fu but after including CarrierWave::MimetypeFu I got unitilzied constant CarrierWave::MimetypeFu

Do you have any experience with it?

jedi
  • 2,003
  • 5
  • 28
  • 66
  • Just throwing off some random ideas, have you required the file before including it? Usually, uninitialized constant errors happen in a file cannot be found or not included before being used. – jemonsanto Apr 09 '18 at 10:22
  • In rails it is required automagically by default :) Anyway, I've just tried more in-depth debugging and here is what I've found. Carrierwave changes the content type probably based off of file extension. `file -I this_is_pdf.jpg => text/plain` `uploader = PhotoUploader.new.cache!("this_is_pdf.jpg")` `uploader.file.content_type => image/jpg` – jedi Apr 09 '18 at 11:14

2 Answers2

4

I'm answering this two year old question. CarrierWave content type whitelisting relying just on file extension. I tried changing an SWF file's extension to JPG and got a lengthy error direct on UI:

Validation failed: Photograph Failed to manipulate with MiniMagick, maybe it is not an image? Original Error: 'convert /home/../projects/rails/../tmp/1588146379-380224569365897-0005-2916/android-916817f.png -auto-orient -resize 170x200^ -sharpen 0x1 -gravity Center -background rgba(255,255,255,0.0) -extent 170x200 /tmp/image_processing20200429-20696-ek1vs1.png` failed with error:

Spend whole night searching for the solution but got too little on this topic. This answer and this wiki helped me.

class PhotoUploader < CarrierWave::Uploader::Base
  include CarrierWave::MiniMagick

  storage :file

  before :process, :validate

  process resize_to_fill: [170, 200], convert: :jpg
  .
  .
  def validate(file)
    begin
      image = MiniMagick::Image.open(file.path)
    rescue
      raise "Image format isn't valid"
    end
  end
end
Ghazi
  • 966
  • 8
  • 15
0

Answer

You should be using

  def content_type_allowlist
    /image\//
  end

This is at least what the documentation says. This question was asked a while ago, so the documentation could've reflected something quite different back then, not sure. I suppose it only matters what to do now.

In the application that I'm running: when attempting to upload a zip file, where my content_type_allowlist only allows image content types, I get an error with the model.

Which is expected, I should only be allowed image types.

Code

task_attached_files.rb

class TaskAttachedFile < ActiveRecord::Base
  attr_accessible :task_id, :file
  mount_uploader :file, FileUploader
end

file_uploader.rb

class FileUploader < CarrierWave::Uploader::Base
  include CarrierWave::Compatibility::Paperclip
  storage :fog

  def paperclip_path
    "shared/system/:class/:attachment/:id_partition/:style/:basename"
  end

  def content_type_allowlist
    /image\//
  end
end

Thomas
  • 2,622
  • 1
  • 9
  • 16