Skip to content

Commit

Permalink
stop caching mime types globally
Browse files Browse the repository at this point in the history
Unknown mime types should not be cached globally.  This global cache
leads to a memory leak and a denial of service vulnerability.

CVE-2016-0751
  • Loading branch information
tenderlove committed Jan 22, 2016
1 parent a6fa396 commit 127967b
Showing 1 changed file with 16 additions and 2 deletions.
18 changes: 16 additions & 2 deletions actionpack/lib/action_dispatch/http/mime_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def #{method}(*)

SET = Mimes.new
EXTENSION_LOOKUP = {}
LOOKUP = Hash.new { |h, k| h[k] = Type.new(k) unless k.blank? }
LOOKUP = {}

def self.[](type)
return type if type.is_a?(Type)
Expand Down Expand Up @@ -85,7 +85,7 @@ class << self
Q_SEPARATOR_REGEXP = /;\s*q=/

def lookup(string)
LOOKUP[string]
LOOKUP[string] || Type.new(string)
end

def lookup_by_extension(extension)
Expand Down Expand Up @@ -204,9 +204,12 @@ def unregister(symbol)
end
end

attr_reader :hash

def initialize(string, symbol = nil, synonyms = [])
@symbol, @synonyms = symbol, synonyms
@string = string
@hash = [@string, @synonyms, @symbol].hash
end

def to_s
Expand Down Expand Up @@ -240,6 +243,13 @@ def ==(mime_type)
end
end

def eql?(other)
super || (self.class == other.class &&
@string == other.string &&
@synonyms == other.synonyms &&
@symbol == other.symbol)
end

def =~(mime_type)
return false if mime_type.blank?
regexp = Regexp.new(Regexp.quote(mime_type.to_s))
Expand All @@ -262,6 +272,10 @@ def respond_to?(method, include_private = false) #:nodoc:
super || method.to_s =~ /(\w+)\?$/
end

protected

attr_reader :string, :synonyms

private
def method_missing(method, *args)
if method.to_s =~ /(\w+)\?$/
Expand Down

1 comment on commit 127967b

@kevingriffin
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does the workaround you posted work? It seems like the hash gets reinitialized, but isn't this an issue with MIME types getting cached after boot in response to malicious requests? It seems like the default value proc the hash receives is the same too. Just curious!

Please sign in to comment.