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

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

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

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

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

Категории

Все категории
Loading categories
jellyfin-suggestions-idor — Jellyfin Server 12.2 — высокий уровень — удалённо — IDOR — GET /Items/Suggestions omit-userId раскрывает скрытый путь библиотеки и идентификаторы | Kitploit
Инструменты/GitHubGitHub/abraxas/jellyfin-suggestions-idor
Анализ уязвимостейЭксплуатация веб-приложенийСбор информацииВеб-безопасностьТестирование на ПроникновениеБезопасность APIЛаборатории и Практика
GitHub
abraxas/jellyfin-suggestions-idor

jellyfin-suggestions-idor

Jellyfin Server 12.2 — высокий уровень — удалённо — IDOR — GET /Items/Suggestions omit-userId раскрывает скрытый путь библиотеки и идентификаторы

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

Популярное

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

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

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

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

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

Abraxas Labs - jellyfin-suggestions-idor

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

jellyfin-suggestions-idor

Jellyfin Server 12.2 - Jellyfin

Класс: IDOR. Доступ: удалённый (любой аутентифицированный пользователь без прав администратора).

GET /Items/Suggestions защищён только атрибутом [Authorize]. Когда userId опущен, SuggestionsController.GetSuggestions устанавливает user = null и никогда не вызывает RequestHelpers.GetUserId. InternalItemsQuery(null) не вызывает SetUser. LibraryManager.GetItemsResult пропускает AddUserToQuery. new DtoOptions() включает ItemFields.Path. GetBaseItemDtos(..., user: null) пропускает IsVisible.

GHSA-9x85 научил GetUserId (при пропуске берутся claims; чужой GUID даёт 403). ItemsController.GetItems всегда его использует. Suggestions — нет. Устаревший GET /Users/{userId}/Suggestions всегда имеет GUID в маршруте, поэтому этот родственный эндпоинт действительно проходит через GetUserId.

Аккаунт с ограничениями выгружает названия, ID, описания, идентификаторы провайдеров и путь в файловой системе для библиотек, к которым он не приписан. Эти GUID воспроизводятся на неаутентифицированном GET /Videos/{id}/stream.

IDCVE пока нет
CWECWE-639 / CWE-862
CVSSВысокий: 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 (ca0f16eb7c195f720a1493ed469a27c4657db0c6), образ jellyfin/jellyfin:12.2
Аутентификацияаутентифицированный (любой не-администратор, включая детский аккаунт / аккаунт со скрытой библиотекой)
ЛицензияGNU Affero GPL v3.0
Лабораториятолько 127.0.0.1:18790

Остаток №1 из Jellyfin 12.2 leftovers. Тот же пин, другие пакеты: jellyfin-svg-gzip (остаток GHSA-cf3c gzip data:image/png), jellyfin-playlist-itemids (остаток GHSA-9x85 ItemIds + неаутентифицированный поток), jellyfin-ffmpeg-colonslash (остаток GHSA-wwwm кавычки URL .strm). Этот пакет — тот, что выгружает скрытую библиотеку.

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

Любой аутентифицированный не-администратор, включая детский аккаунт / аккаунт со скрытой библиотекой / аккаунт с MaxParentalRating. Нужен обычный пользовательский токен. Без администратора, без API-ключа. Пароли они не меняют. Администратора не создают. Они инвентаризируют библиотеки, к которым не приписаны, включая путь в файловой системе, а затем воспроизводят эти GUID.

Таблица привилегий (исчерпывающая). Тот же уровень, что и Signal-Server Dropwizard admin: метод + путь, что даёт этот вызов, разведка против целостности против доступности, доказано в лаборатории против выведено, смежная поверхность, которая остаётся закрытой.

ОсьМетод + путьЧто даётПроисхождение
РазведкаGET /Items/Suggestions без userId (необязательные limit / mediaType / type)Неограниченный рекурсивный список элементов: Name, Id, Overview, идентификаторы провайдеров, путь в файловой системе, метаданные изображений библиотек, к которым вызывающий не назначен, включая папки, выданные только скрытому пользователю. ACL папок, родительский рейтинг и разрешённые теги не применяются.Доказано в лаборатории. Ограниченный labuser (EnableAllFolders=false, только EnabledFolders=PublicB): GET /Items witness=0; Suggestions witness=1
РазведкаТо же без limitInternalItemsQuery.Limit остаётся неустановленным; репозиторий возвращает весь набор совпадений (вся таблица элементов, случайный порядок)Исходный код (SuggestionsController.cs:70-95)
Разведканеаутентифицированный GET /Videos/{itemId}/stream с GUID из этого спискаБайты этого файла от имени UID jellyfinИсходный код (у VideosController нет атрибута [Authorize] на классе; StreamingHelpers GetItemById без пользователя). Поток проверен в лаборатории в соседнем остатке jellyfin-playlist-itemids, не в этом пакете
Целостностьнет в SuggestionsНет записи пароля, политики, избранного или сессииЗакрыто
Доступностьнет в SuggestionsНет DoS сверх обычной стоимости запросаЗакрыто

Остаётся закрытым на этой фиксации

ОсьМетод + путьПочему закрыто
РазведкаGET /Items?userId= и GET /Items?parentId=<hiddenFolder>Всегда GetUserId + IsVisible (ItemsController.cs:265, 342-350)
РазведкаGET /Playlists/{id}/Items?userId=GetUserId (PlaylistsController.cs:524). Класс GHSA-9x85, исправлен
РазведкаGET /Items/Suggestions?userId=<other>Чужой GUID всё равно попадает в GetUserId и возвращает 403 для не-администратора. Доказано в лаборатории (impersonate-403=yes)
Разведкаустаревший GET /Users/{userId}/SuggestionsGUID маршрута обязателен, поэтому он действительно вызывает GetUserId
ЦелостностьPOST /Users/Password?userId=AssertCanUpdateUser
ЦелостностьPOST /Users/{id}/PolicyRequiresElevation
Целостностьустройства, сессии, AddAdditionalUserтолько повышение прав или собственная сессия
РазведкаGET /Users / GET /Users/{id}UserDto + политика (GUID папок, бит администратора), а не содержимое библиотек или хэши. Перечисление домашних пользователей, не этот остаток

Я не заявляю о RCE через DLL плагина, обратной оболочке или краже паролей. Дамп — это каталог (и Path) библиотек, к которым вызывающий не был назначен. Продолжение в виде потока по GUID — давнее поведение Jellyfin HTML5/DLNA; этот остаток — то, что перечисляет ID.

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

v12.2 закрыла волну GHSA 12.0. Я всё равно остался на этом теге и прочитал каждый запрос userId рядом с RequestHelpers.GetUserId. Items всегда его использует. Suggestions ветвится: пустой userId -> user = null, никогда не GetUserId. Вот это и есть остаток.

run.sh создаёт две библиотеки фильмов (PrivateA с именем-свидетелем, PublicB), завершает мастер настройки, создаёт labuser с EnableAllFolders=false и только EnabledFolders=PublicB, затем сравнивает GET /Items с GET /Items/Suggestions.

Уже зафиксированные неверные пути: считать GET /Items утечкой (он ограничен областью); считать Suggestions?userId=<admin> утечкой (403); считать устаревший маршрут /Users/{userId}/Suggestions дырой (у него есть GUID, поэтому он вызывает GetUserId); заявлять неаутентифицированный поток как баг этого пакета (соседний остаток); обратная оболочка. Театр.

Скачать инструмент