
Jellyfin Server 12.2 - 높음 - 원격 - SSRF - gzip data:image/png GHSA-cf3c의 잔여물이 여전히 http 및 file을 가져옴
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · jellyfin-svg-gzip
분류: SSRF + 파일 읽기 + memex
도달 범위: 원격 (인증된 모든 사용자 POST /UserImage; 래스터화는 비인증 GET /UserImage)
Jellyfin Server 12.2 (ca0f16eb) - Jellyfin. Svg.Skia 3.7.0.
GHSA-cf3c-8m59-2vhx는 프로필 SVG의 외부 http 및 file href를 차단했습니다. 12.2는 여전히 Svg.Skia 3.7.0을 고정하고 있습니다. SvgDocument.ResolveExternalImages = ExternalType.None은 3.7.0 ImageDrawable에서 무시됩니다. SvgSecurityValidator.ValidateDataUri는 미디어 타입이 정확히 image/svg+xml이 아닌 모든 data URI에 대해 gzip 검사 이전에 허용을 반환합니다. Svg.Skia GetImageFromDataUri는 mimeType.StartsWith("image/")와 gzip 매직을 확인한 뒤 Jellyfin의 재검사 없이 LoadSvgz를 호출합니다. 내부 SVG의 http(s) / file href는 WebRequest.Create로 전달됩니다. 이것이 원래 GHSA-cf3c의 싱크입니다.
인증된 모든 사용자가 gzip-png로 감싼 SVG를 업로드합니다. 해당 프로필 이미지에 대한 비인증 GET 요청은 래스터화 중에 서버가 공격자의 http / https / file://을 가져오게 만듭니다.
| ID | 아직 CVE 없음 |
| 분류 | SSRF + 파일 읽기 + memex |
| 도달 범위 | 원격. 모든 사용자 POST /UserImage. 래스터화는 비인증 GET /UserImage?userId= |
| CWE | CWE-918 / CWE-611 / CWE-400 |
| CVSS | 높음: 7.7 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:L |
| 제품 | Jellyfin Server |
| 영향받는 버전 | 12.2 (ca0f16eb7c195f720a1493ed469a27c4657db0c6), 이미지 jellyfin/jellyfin:12.2, Svg.Skia 3.7.0 |
| 인증 | 인증된 업로드. 비인증 래스터화. |
| 라이선스 | GNU Affero GPL v3.0 |
| 랩 | 127.0.0.1 전용 |
Jellyfin 12.2 leftovers 시리즈의 남은 #2입니다. 자매 항목 #1 Suggestions IDOR. 동일한 고정 버전: playlist ItemIds, FFmpeg colon-slash.
행위자는 로그인한 모든 Jellyfin 사용자입니다. 프로필 이미지는 관리자 전용이 아닙니다. 래스터화에는 세션이 필요하지 않습니다.
| 축 | 메서드 + 경로 | 부여되는 것 | 출처 |
|---|---|---|---|
| 정찰 | POST /UserImage (Content-Type: image/svg+xml, BASE64 본문) 후 비인증 GET /UserImage?userId= | Skia가 래스터화하는 동안 서버가 공격자의 http/https(루프백, RFC1918, 링크-로컬/IMDS)를 GET | 랩에서 입증됨. 오라클 호스트명 oracle:8080, hits=1, 경로에 witness 포함 |
| 정찰 | 동일 | 요청자가 다운로드하는 PNG/WebP/JPEG에 file:// 바이트가 그려짐 (이미지로 디코딩되는 경우) | 추론됨. GHSA-cf3c와 동일한 WebRequest.Create 싱크 |
| 가용성 | 동일, 내부 file:///dev/urandom | 관리되는 힙에 무제한 읽기 데이터가 유지됨. 재업로드 없이 이후 모든 이미지 GET마다 반복됨 | 추론됨. GHSA-cf3c에서 측정됨 |
| 무결성 | 없음 | 사용자 정책 쓰기, 플러그인 설치, 세션 탈취 없음 | 차단됨 |
닫힌 상태 유지: 외부 SVG의 직접 http/file href(실험실: GET은 image/svg+xml로 유지됨, 오라클 0); 중첩된 data:image/svg+xml(gzip 포함 재스캔됨); DTD SYSTEM; GHSA-vcmh 인라인 XSS(Content-Disposition: attachment 및 래스터화); 플러그인 이미지 경로 탐색; Magick/PDF. RCE 아님. 세션 XSS 아님. SSRF 본문은 Skia가 그리는 것이지 원시 HTTP 응답이 아니다.
12.2는 GHSA-cf3c 사전 스캔이 이미 포함된 태그다. 그래도 나는 그대로 두었다. 여전히 가져오는 라이브러리 앞에 검증기를 추가하는 패치는 선물과 같다: 검증기가 무엇을 순회하는지 읽은 다음, 라이브러리가 여전히 무엇을 파싱하는지 물으면 된다.
Directory.Packages.props는 여전히 Svg.Skia 3.7.0을 고정하고 있다. 업스트림 wieslawsoltes/Svg.Skia#448(#501에서 수정됨): ImageDrawable은 ResolveExternalImages를 전혀 참조하지 않는다. Jellyfin의 세 ExternalType.None 할당은 이 고정 버전에서는 아무 효과가 없다. Renovate #17076은 해당 태그에 포함되지 않았다.
그러면 사전 스캔이 유일한 관문이다. ValidateReference는 모든 비프래그먼트, 비data: href를 거부한다. 중첩된 image/svg+xml은 gzip을 포함해 다시 파싱된다. SvgSecurityValidator.cs:169-173의 주석은 다른 미디어 타입은 래스터이며 0x1F 0x8B 순회 이전에 허용을 반환한다고 말한다. Svg.Skia 3.7.0의 GetImageFromDataUri는 이와 다르다: gzip 매직을 가진 모든 image/*는 LoadSvgz다.
이미 기록된 잘못된 방향들: 네거티브 컨트롤이 image/svg+xml로 유지된다는 이유로 GHSA-cf3c를 닫힌 것으로 취급하기; 중첩된 data:image/svg+xml gzip(재스캔됨); DTD SYSTEM; GHSA-vcmh 인라인 XSS; 플러그인 이미지 경로 탐색; Magick/PDF; 관리자 RemoteImages/Download(의도된 아트워크 가져오기); 이 잔여 문제가 아닌 픽셀 폭탄 DoS; 리버스 셸. 다 연극일 뿐이다.
python3 jellyfin-svg-gzip-Abraxas-Labs.py
또는:
cd lab
./run.sh
루프백 전용: Jellyfin http://127.0.0.1:18780, 오라클 http://127.0.0.1:18781. 이미지 jellyfin/jellyfin:12.2. 오라클은 1x1 PNG를 반환하고 요청 경로를 기록한다. Skia가 가져오는 대상은 Compose 호스트명 oracle:8080이다.
부정 케이스: 이미지 href가 http://oracle:8080/negative.png인 프로필 SVG를 POST한다. GET은 image/svg+xml로 유지되고, 오라클은 0이다. 긍정 케이스: href가 http://oracle:8080/JELLYFIN-SVG-SVGSKIA-WITNESS.png인 내부 SVG를 gzip으로 압축하여 외부 SVG에 data:image/png;base64로 감싼다. GET은 image/png이고, 오라클은 1이다.
SUCCESS jellyfin-svg-gzip gzip-png-ssrf hits=1 negative=0 JELLYFIN-SVG-SVGSKIA-WITNESS
증인 전용. 익스플로잇 페이로드 없음. 리버스 셸 없음. 승인된 랩. 루프백.
선언된 미디어 타입이 image/svg+xml이 아니더라도 SvgSecurityValidator에서 gzip 및 중첩 데이터 URI를 순회하도록 한다. 또는 Svg.Skia를 ImageDrawable ExternalType.None 무시(업스트림 #448 / #501, renovate #17076은 이 태그에 없음) 이후 버전으로 올린다. 둘 다. 라이브러리 플래그가 의도된 킬 스위치다. 검증기는 라이브러리가 무엇을 파싱할지에 대해 거짓말을 해서는 안 된다.
ca0f16eb7c195f720a1493ed469a27c4657db0c6)SvgSecurityValidator.cs · SkiaEncoder.cs · ImageController.csGNU Affero GPL v3.0. LICENSE 참조. 루프백 랩 전용. 보증 없음.