Skip to content
KitploitKITPLOIT
ИнструментыЭксплойтыБлог
Log in
Отправить
ИнструментыЭксплойтыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

ЛентыКонтактыКонфиденциальность© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
jellyfin-playlist-itemids — Jellyfin Server 12.2 — высокий уровень — удалённо — IDOR — оставшиеся ItemIds публичного плейлиста из GHSA-9x85, затем неаутентифицированный поток | Kitploit
Инструменты/GitHubGitHub/abraxas/jellyfin-playlist-itemids
Анализ уязвимостейЭксплуатация веб-приложенийЭксфильтрация данныхСбор информацииВеб-безопасностьТестирование на ПроникновениеБезопасность APIЛаборатории и Практика
GitHubabraxas/jellyfin-playlist-itemids

jellyfin-playlist-itemids

Jellyfin Server 12.2 — высокий уровень — удалённо — IDOR — оставшиеся ItemIds публичного плейлиста из GHSA-9x85, затем неаутентифицированный поток

Репозиторий
31 день назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

Abraxas Labs - jellyfin-playlist-itemids

abraxaslabs.tech  ·  github.com/abraxas  ·  @abraxas_null  ·  [email protected]  ·  jellyfin-playlist-itemids

jellyfin-playlist-itemids

Класс: IDOR Доступ: Удалённый (любой пользователь, который видит публичный плейлист)

Jellyfin Server v12.2 (ca0f16eb7c195f720a1493ed469a27c4657db0c6) - Jellyfin

GHSA-9x85 исправил GET /Playlists/{id}/Items с помощью GetUserId и Where(i => i.Item2.IsVisible(user)). Для GET /Playlists/{id} этот фильтр не был добавлен. ItemIds — это GetManageableItems() без IsVisible для дочерних элементов. GetPlaylistForUser требует лишь видимости плейлиста.

CreatePlaylistDto.IsPublic по умолчанию true. Плейлисты OpenAccess являются IsVisible для других пользователей (HasParentalAllowedChild всё равно позволяет второму пользователю видеть плейлист). У неаутентифицированного GET /Videos/{id}/stream нет [Authorize]. StreamingHelpers загружает GetItemById без пользователя.

Пользователь, который видит публичный плейлист, читает GUID приватных дочерних элементов из ItemIds, а затем стримит файлы без токена.

IDCVE пока нет
КлассIDOR (остаток ItemIds плейлиста от GHSA-9x85, затем неаутентифицированный стрим)
ДоступУдалённый (любой пользователь, который видит публичный плейлист)
CWECWE-639, CWE-862
CVSSHigh: 6.5 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
ПродуктJellyfin Server
Затронутоv12.2 (ca0f16eb) образ jellyfin/jellyfin:12.2
Аутентификацияаутентификация для GET плейлиста; отсутствует для стрима
ЛицензияGNU Affero GPL v3.0
Лабораториятолько 127.0.0.1:18800

Остаток #3 из Jellyfin 12.2 leftovers. Остаток #1 (самый важный): jellyfin-suggestions-idor. Тот же пин: jellyfin-svg-gzip · jellyfin-ffmpeg-colonslash.

Что может сделать атакующий

Жертва и атакующий — два пользователя на одном сервере с непересекающимися библиотеками (детские против взрослых или скрытая папка). Жертва добавляет приватный фильм в публичный плейлист. При создании через тело запроса IsPublic по умолчанию true, так что это обычный случай, а не шаринг. Атакующий входит под ограниченной учётной записью, читает объект плейлиста, а затем получает файл без заголовка Authorization.

Это GUID медиафайлов из библиотек, к которым атакующий не привязан, а затем полный файл через стрим. Это не перебор названий плейлистов. Добавление/создание по-прежнему отбрасывает невидимые элементы.

Разведка (подтверждено в лаборатории)

МетодПутьПривилегия
GET/Playlists/{playlistId}GUID дочерних элементов видимого плейлиста (ItemIds из GetManageableItems(), без IsVisible для дочерних элементов). Также Shares[].UserId / CanEdit (userId получателей доступа). Лаборатория: GET /Playlists/{id}/Items пользователя B пуст; GET /Playlists/{id} с тем же id перечислил приватный GUID a2bf95146e44897be6fb09020a82eb52.

GetPlaylistForUser требует лишь видимости самого плейлиста. Достаточно OpenAccess плюс HasParentalAllowedChild (который пропускает проверку разрешённых тегов). Исправленный маршрут Items служит контролем: он по-прежнему фильтрует.

Конфиденциальность (подтверждено в лаборатории)

МетодПутьПривилегия
GET/Videos/{itemId}/stream?static=trueБайты приватного медиа. Нет [Authorize]. StreamingHelpers выполняет GetItemById<BaseItem>(id) без пользователя. В лаборатории: неаутентифицированный запрос 200, 1142 байта, свидетель JELLYFIN-PLAYLIST-ITEMIDS-WITNESS в теле.
GET/Audio/{itemId}/streamТот же приёмник для аудио. Тот же помощник, тот же неограниченный поиск.

Аутентифицированный HLS GET /Videos/{itemId}/master.m3u8 использует тот же путь GetItemById (DynamicHlsController имеет [Authorize] на уровне класса). В лаборатории проверялся неаутентифицированный прогрессивный поток, а не HLS.

Целостность (закрыто)

МетодПутьПривилегия
POST/Playlists/{id}/Items и создание IdsЗакрыто. Playlist.GetPlaylistItems выполняет IsVisible. Приватные GUID отбрасываются, а не связываются.

Смежная поверхность, которая остаётся закрытой

  • Добавление приватных GUID в собственный плейлист.
  • InstantMix (привязанный к пользователю GetItemById(id, user)).
  • Коллекции (EnableCollectionManagement по умолчанию false; FilterLinkedChildrenPerUser).
  • Префикс транскодирования GHSA-hw73 (ValidateTranscodePath удерживает устаревшие HLS-сегменты внутри каталога транскодирования).
  • Подмена userId в Items по GHSA-9x85 (GetUserId возвращает 403 для чужого id).
  • Листинг приватных дочерних элементов через GET /Playlists/{id}/Items (исправленный маршрут; в лаборатории items-filtered=yes).

Никакой записи паролей/политик. Никакой установки плагинов. Никакого shell.

Один только ACL папки (EnabledFolders) не скрыл дочерний элемент на /Items в этой лаборатории. AllowedTags=["lab-public"] заставил IsVisible отбросить его. ItemIds и неаутентифицированный поток не обращаются к этому фильтру.

Как я это нашёл

Я зафиксировал jellyfin/jellyfin v12.2 (ca0f16eb). Двадцать поисков по исходникам на остатках волны GHSA 12.0. GHSA-9x85 научил GetPlaylistItems фильтровать дочерние элементы. Я спросил, получил ли GetPlaylist тот же Where. Не получил. Эндпоинты потоковой передачи так и не обзавелись привязанным к пользователю GetItemById.

Неверный поворот: трактовка EnabledFolders как скрытия Items. IsVisible фильма — это родительский контроль/теги, а не ACL папки. В лаборатории пришлось задать AllowedTags, чтобы исправленный маршрут Items стал пустым. Это контроль. Остаток его не использует.

Лаборатория

git clone https://github.com/abraxas/jellyfin-playlist-itemids
cd jellyfin-playlist-itemids
python3 jellyfin-playlist-itemids-Abraxas-Labs.py

Или:

cd lab
./run.sh

Цель — только http://127.0.0.1:18800. Образ jellyfin/jellyfin:12.2. run.sh создаёт два крошечных mp4 (PrivateA — файл-свидетель, PublicB — пустышка). Мастер создаёт labadmin, обе папки, затем labuser с EnableAllFolders=false, EnabledFolders=PublicB, AllowedTags=["lab-public"]. Администратор помещает приватный фильм в публичный плейлист. Loopback. Только свидетель. Требуются Docker и ffmpeg для создания файлов.

SUCCESS JELLYFIN-PLAYLIST-ITEMIDS items-filtered=yes itemids-leak=yes unauth-stream=200 openAccess=yes playlist=e4798134497195ff4733dde62428e8d8 private=a2bf95146e44897be6fb09020a82eb52 witness-in-stream=yes witness-in-playlist-json=yes JELLYFIN-PLAYLIST-ITEMIDS-WITNESS
Скачать инструмент