Skip to content

Commit

Permalink
Fix Content-Type allowlist bypass vulnerability
Browse files Browse the repository at this point in the history
  • Loading branch information
mshibuya committed Nov 29, 2023
1 parent 2f91bee commit 39b282d
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 1 deletion.
2 changes: 1 addition & 1 deletion lib/carrierwave/uploader/content_type_whitelist.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def check_content_type_whitelist!(new_file)
def whitelisted_content_type?(content_type)
Array(content_type_allowlist).any? do |item|
item = Regexp.quote(item) if item.class != Regexp
content_type =~ /#{item}/
content_type =~ /\A#{item}/
end
end

Expand Down
27 changes: 27 additions & 0 deletions spec/uploader/content_type_whitelist_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,33 @@
expect { uploader.cache!(ruby_file) }.not_to raise_error
end
end

context "with a crafted content type" do
before do
allow(bork_file).to receive(:content_type).and_return('text/plain; image/png')
allow(uploader).to receive(:content_type_allowlist).and_return('image/png')
end

it "does not allow spoofing" do
expect { uploader.cache!(bork_file) }.to raise_error(CarrierWave::IntegrityError)
end
end

context "when the allowlist contains charset" do
before do
allow(uploader).to receive(:content_type_allowlist).and_return(%r{text/plain;\s*charset=utf-8})
end

it "accepts the content with allowed charset" do
allow(bork_file).to receive(:content_type).and_return('text/plain; charset=utf-8')
expect { uploader.cache!(bork_file) }.not_to raise_error
end

it "rejects the content without charset" do
allow(bork_file).to receive(:content_type).and_return('text/plain')
expect { uploader.cache!(bork_file) }.to raise_error(CarrierWave::IntegrityError)
end
end
end

context "when there is a whitelist" do
Expand Down

0 comments on commit 39b282d

Please sign in to comment.