Skip to content

Commit c2989c5

Browse files
authored
GHSA/SYNC: 1 new advisory (#1078)
* GHSA/SYNC: 1 new advisory * Removed partial sentence and added patch commit URL
1 parent 851dcb1 commit c2989c5

1 file changed

Lines changed: 80 additions & 0 deletions

File tree

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

0 commit comments

Comments
 (0)