🇰🇷 한글 설명
CarrierWave의 content_type_denylist 검사에서 정규식 메타문자를 이스케이프하지 않아, image/svg+xml 같은 항목이 실제 MIME 타입과 일치하지 않고 차단이 조용히 무력화됩니다. 2.2.7 및 3.1.3 이전 버전이 영향을 받으며, 이로 인해 SVG를 통한 저장형 XSS가 발생할 수 있습니다.
💡 쉬운 설명
업로드 파일 종류를 막으려던 차단 목록이 제대로 작동하지 않아 위험한 SVG 파일이 그대로 업로드될 수 있습니다. 해당 파일이 웹사이트에서 보여지면 악성 스크립트가 실행될 수 있습니다.
🇺🇸 원문 (English)
CarrierWave is a framework to upload files from Ruby applications. In versions prior to 2.2.7 and 3.1.3, the content_type_denylist check fails to escape regex metacharacters in string entries, causing the denylist to silently not match the content types it is intended to block. In lib/carrierwave/uploader/content_type_denylist.rb:57, denylist entries are interpolated directly into a regex without Regexp.quote or anchoring, so an entry such as image/svg+xml becomes the pattern /image\/svg+xml/, in which + is treated as a quantifier rather than a literal character and therefore never matches the real MIME type image/svg+xml. This is inconsistent with the allowlist implementation, which correctly applies both Regexp.quote and a \A anchor. Other content types containing regex metacharacters, such as application/xhtml+xml, are affected as well. As a result, any application that relies on content_type_denylist to block image/svg+xml, most commonly to prevent stored XSS, is silently unprotected. An attacker can upload an SVG file containing arbitrary JavaScript; if the application serves that SVG inline from its own origin, the script executes in the victim's browser, resulting in stored XSS. This issue has been fixed in versions 2.2.7 and 3.1.3.
📍 영향받는 시스템
CarrierWave 2.2.7 미만 및 3.1.3 미만 버전을 사용하는 Ruby 애플리케이션 (content_type_denylist 사용 시)
⚔️ 공격 벡터
공격자가 자바스크립트가 포함된 SVG 파일을 업로드하고, 애플리케이션이 이를 동일 출처에서 인라인으로 제공하면 피해자 브라우저에서 스크립트가 실행됨
🛡️ 대응 방법
CarrierWave를 2.2.7 또는 3.1.3 이상으로 업그레이드하고, 필요 시 allowlist 방식 사용 및 업로드 파일의 Content-Disposition 설정을 적용
🔧 검증 코드
출력된 버전이 2.2.7 또는 3.1.3 이상이면 패치된 것이며, 그보다 낮으면 취약한 버전이므로 업그레이드가 필요합니다.
bundle exec gem list carrierwave 2>/dev/null | grep carrierwave