Skip to content

Commit 2eae904

Browse files
jasnowRubySec CI
authored andcommitted
Updated advisory posts against rubysec/ruby-advisory-db@c2989c5
1 parent ac9ab6c commit 2eae904

1 file changed

Lines changed: 87 additions & 0 deletions

File tree

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
---
2+
layout: advisory
3+
title: 'CVE-2026-44587 (carrierwave): CarrierWave has a denylisted_content_type bypass
4+
via Unescaped Regex Metacharacters'
5+
comments: false
6+
categories:
7+
- carrierwave
8+
advisory:
9+
gem: carrierwave
10+
cve: 2026-44587
11+
ghsa: 7g26-2qgj-chfg
12+
url: https://www.cve.org/CVERecord?id=CVE-2026-44587
13+
title: CarrierWave has a denylisted_content_type bypass via Unescaped Regex Metacharacters
14+
date: 2026-05-27
15+
description: |-
16+
### Summary
17+
18+
CarrierWave's content_type_denylist check fails to escape regex
19+
metacharacters in string entries, causing the denylist to silently
20+
not match the content types it is intended to block.
21+
22+
**Note**: CarrierWave is aware `#content_type_denylist is deprecated
23+
for the security reason`, but it still used by developers, and the
24+
problem here isn't denylist allows any filetype, and thats not a
25+
vulnerability in carrierwave, its an implementation problem in
26+
developers using CarrierWave, the problem is its denylist entries
27+
are interpolated directly into a regex without `Regexp.quote` or
28+
anchoring. The denylist is still useful when developers want to
29+
ban specific content types but allow everything else.
30+
31+
### Details
32+
33+
In `lib/carrierwave/uploader/content_type_denylist.rb:57`, string
34+
denylist entries are interpolated directly into a regex without
35+
`Regexp.quote` or anchoring:
36+
37+
```ruby
38+
def denylisted_content_type?(denylist, content_type)
39+
Array(denylist).any? { |item| content_type =~ /#{item}/ }
40+
end
41+
42+
The entry "image/svg+xml" becomes the regex /image\/svg+xml/ where +
43+
is a quantifier meaning "one or more g", not a literal +. This
44+
regex never matches the real MIME type "image/svg+xml" which contains
45+
a literal +. This is inconsistent with the allowlist implementation
46+
at lib/carrierwave/uploader/content_type_allowlist.rb:53-57, which
47+
correctly applies both Regexp.quote and a \A anchor:
48+
49+
rubydef allowlisted_content_type?(allowlist, content_type)
50+
Array(allowlist).any? do |item|
51+
item = Regexp.quote(item) if item.class != Regexp
52+
content_type =~ /\A#{item}/
53+
end
54+
end
55+
```
56+
57+
Other affected MIME types include `application/xhtml+xml` and any
58+
type containing regex metacharacters.
59+
60+
Fix: Apply Regexp.quote for string entries and anchor with \A,
61+
matching the existing allowlist implementation:
62+
63+
```
64+
rubydef denylisted_content_type?(denylist, content_type)
65+
Array(denylist).any? do |item|
66+
item = Regexp.quote(item) if item.class != Regexp
67+
content_type =~ /\A#{item}/
68+
end
69+
end
70+
```
71+
### Impact
72+
73+
Any application that uses content_type_denylist to block image/svg+xml
74+
— the most common use case, specifically to prevent stored XSS — is
75+
silently unprotected.
76+
cvss_v3: 4.7
77+
patched_versions:
78+
- "~> 2.2.7"
79+
- ">= 3.1.3"
80+
related:
81+
url:
82+
- https://www.cve.org/CVERecord?id=CVE-2026-44587
83+
- https://github.com/carrierwaveuploader/carrierwave/releases
84+
- https://github.com/carrierwaveuploader/carrierwave/commit/21221cc6e260633f7da78c6133a88666a5529d27
85+
- https://github.com/carrierwaveuploader/carrierwave/security/advisories/GHSA-7g26-2qgj-chfg
86+
- https://github.com/advisories/GHSA-7g26-2qgj-chfg
87+
---

0 commit comments

Comments
 (0)