Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DOS vector #795

Closed
ahoward opened this issue Jul 24, 2012 · 2 comments
Closed

DOS vector #795

ahoward opened this issue Jul 24, 2012 · 2 comments

Comments

@ahoward
Copy link

ahoward commented Jul 24, 2012

    ##
    # Returns the contents of the file.
    #
    # === Returns
    #
    # [String] contents of the file
    #
    def read
      if is_path?
        File.open(@file, "rb") {|file| file.read}
      else
        @file.rewind if @file.respond_to?(:rewind)
        @file.read
      end
    end

this probably isn't the best pattern as it loads the entire upload, no matter how big, into memory at once.

@trevorturk
Copy link
Contributor

Ah ha! Good point. Pull requests more than welcome!

@ahoward
Copy link
Author

ahoward commented Jul 24, 2012

i'm brewing another right now

https://github.com/ahoward/carrierwave-mongoid/tree/mongoid-3.0

which is what made me catch it

if anyone else wants to pick up the ball here is how i do it safely in my mongoid adapter

    def GridFS.reading(arg, &block) 
      if arg.respond_to?(:read)
        rewind(arg) do |io|
          block.call(io)
        end   
      else      
        open(arg.to_s) do |io|
          block.call(io)
        end   
      end     
    end

    def GridFS.chunking(io, chunk_size, &block)
      if io.method(:read).arity == 0
        data = io.read
        i = 0 
        loop do
          offset = i * chunk_size
          length = i + chunk_size < data.size ? chunk_size : data.size - offset

          break if offset >= data.size

          buf = data[offset, length]
          block.call(buf)
          i += 1
        end
      else
        while((buf = io.read(chunk_size)))
          block.call(buf)
        end
      end
    end

    def GridFS.rewind(io, &block)
      begin
        pos = io.pos
        io.flush
        io.rewind
      rescue
        nil
      end

      begin
        block.call(io)
      ensure
        begin
          io.pos = pos
        rescue
          nil
        end
      end
    end

GridFS.reading(ioish) do |io|

  GridFS.chunking(io) do |buf|

     stuff_with(buf)

  end

end

that arity check is for carrierwave's sanitized file - fyi.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants