Skip to content

Denial of service vulnerability with maliciously crafted JPEGs (pixel flood attack)

Alexander Lang edited this page Jan 30, 2024 · 4 revisions

Originally reported at https://hackerone.com/reports/390, addressed on paperclip.

A specially crafted JPEG (the original file was named lottapixel.jpg) causes attempts to determine the dimensions of the image to exhaust available memory. From the original report:

The exploit is really simple. I have an image of 5kb, 260x260 pixels. In the image itself I exchange the 260x260 values with 0xfafa x 0xfafa (so 64250x64250 pixels). Now from what I remember your service tries to convert the image once uploaded. By loading the 'whole image' into memory, it tries to allocate 4128062500 pixels into memory, flooding the memory and causing DoS.

As of Carrierwave 3, this issue can be mitigated by declaring a maximum image width/height:

class MyUploader < Carrierwave::Uploader
  def width_range
    0..6000
  end

  def height_range
    0..6000
  end

end

For version < 3.x:

It's easy to address for MiniMagick by adding a method to a CarrierWave initializer:

module CarrierWave
  module MiniMagick
    # check for images that are larger than you probably want
    def validate_dimensions
      manipulate! do |img|
        if img.dimensions.any?{|i| i > 8000 }
          raise CarrierWave::ProcessingError, "dimensions too large"
        end
        img
      end
    end
  end
end

And making validate_dimensions the first process method in your uploader:

class ImageUploader < CarrierWave::Uploader::Base
  include CarrierWave::MiniMagick
  process :validate_dimensions
  ...

See also

carrierwave-bombshelter, a plugin which provides a simple drop-in protection from image bombs (based on the fastimage gem):

class YourUploader < CarrierWave::Uploader::Base
  include CarrierWave::BombShelter
end
Clone this wiki locally