Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

FeedsContactoPrivacidad© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
jellyfin-suggestions-idor — Jellyfin Server 12.2 - Alta - Remota - IDOR - GET /Items/Suggestions omit-userId vuelca la ruta y los IDs de la biblioteca oculta | Kitploit
Herramientas/GitHubGitHub/abraxas/jellyfin-suggestions-idor
Análisis de VulnerabilidadesExplotación de Aplicaciones WebRecopilación de InformaciónSeguridad WebPruebas de PenetraciónSeguridad de APIsLabs y Práctica
GitHub
abraxas/jellyfin-suggestions-idor

jellyfin-suggestions-idor

Jellyfin Server 12.2 - Alta - Remota - IDOR - GET /Items/Suggestions omit-userId vuelca la ruta y los IDs de la biblioteca oculta

Ver Repositorio
1hace 1 díaAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

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

Clase: IDOR. Alcance: Remoto (cualquier usuario autenticado no administrador).

GET /Items/Suggestions solo tiene [Authorize]. Cuando se omite userId, SuggestionsController.GetSuggestions establece user = null y nunca llama a RequestHelpers.GetUserId. InternalItemsQuery(null) no llama a SetUser. LibraryManager.GetItemsResult omite AddUserToQuery. new DtoOptions() incluye ItemFields.Path. GetBaseItemDtos(..., user: null) omite IsVisible.

GHSA-9x85 enseñó a GetUserId (omitir va a los claims; un GUID ajeno es 403). ItemsController.GetItems siempre lo usa. Suggestions no lo hizo. El endpoint heredado GET /Users/{userId}/Suggestions siempre tiene un GUID en la ruta, por lo que ese hermano sí pasa por GetUserId.

Una cuenta restringida vuelca títulos, IDs, descripciones, IDs de proveedor y la ruta del sistema de archivos de bibliotecas a las que no está asignada. Esos GUIDs funcionan en GET /Videos/{id}/stream sin autenticación.

IDaún sin CVE
CWECWE-639 / CWE-862
CVSSAlto: 6.5 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
ProductoJellyfin Server
Afectadov12.2 (ca0f16eb7c195f720a1493ed469a27c4657db0c6), imagen jellyfin/jellyfin:12.2
Autenticaciónautenticado (cualquier no administrador, incluida una cuenta infantil / de biblioteca oculta)
LicenciaGNU Affero GPL v3.0
Laboratoriosolo 127.0.0.1:18790

Residuo n.º 1 de Jellyfin 12.2 leftovers. Misma versión fijada, otros paquetes: jellyfin-svg-gzip (residuo de GHSA-cf3c gzip data:image/png), jellyfin-playlist-itemids (residuo de GHSA-9x85 ItemIds + stream sin autenticación), jellyfin-ffmpeg-colonslash (residuo de GHSA-wwwm comillas de URL .strm). Este paquete es el que vuelca la biblioteca oculta.

Qué puede hacer un atacante

Cualquier usuario autenticado no administrador, incluida una cuenta infantil / de biblioteca oculta / con MaxParentalRating. Necesita un token de usuario normal. Sin administrador, sin clave de API. No cambian contraseñas. No crean administradores. Inventarían bibliotecas a las que no fueron asignados, incluida la ruta del sistema de archivos, y luego reproducen esos GUIDs.

Tabla de privilegios (exhaustiva). Mismo criterio que Signal-Server Dropwizard admin: método + ruta, qué concede esa llamada, reconocimiento vs integridad vs disponibilidad, probado en laboratorio vs inferido, superficie adyacente que permanece cerrada.

EjeMétodo + rutaOtorgaProcedencia
ReconGET /Items/Suggestions sin userId (opcional limit / mediaType / type)Lista recursiva de elementos sin ámbito: Name, Id, Overview, IDs de proveedor, ruta del sistema de archivos, metadatos de imagen de bibliotecas a las que el llamador no está asignado, incluidas carpetas asignadas solo a un usuario oculto. No se aplican ACL de carpeta, clasificación parental ni etiquetas permitidas.Probado en laboratorio. labuser restringido (EnableAllFolders=false, solo EnabledFolders=PublicB): GET /Items testigo=0; Suggestions testigo=1
ReconIgual con limit omitidoInternalItemsQuery.Limit queda sin establecer; el repositorio devuelve el conjunto completo de coincidencias (toda la tabla de elementos, orden aleatorio)Fuente (SuggestionsController.cs:70-95)
ReconGET /Videos/{itemId}/stream sin autenticación con un GUID de esa listaBytes de ese archivo como el UID de jellyfinFuente (VideosController no tiene [Authorize] a nivel de clase; StreamingHelpers GetItemById sin un usuario). El stream se probó en laboratorio en el residuo hermano jellyfin-playlist-itemids, no en este paquete
Integridadninguno en SuggestionsSin escritura de contraseña, política, favorito ni sesiónCerrado
Disponibilidadninguno en SuggestionsSin DoS más allá del coste ordinario de consultaCerrado

Permanece cerrado en este pin

EjeMétodo + rutaPor qué está cerrado
ReconGET /Items?userId= y GET /Items?parentId=<hiddenFolder>Siempre GetUserId + IsVisible (ItemsController.cs:265, 342-350)
ReconGET /Playlists/{id}/Items?userId=GetUserId (PlaylistsController.cs:524). Clase GHSA-9x85, parcheado
ReconGET /Items/Suggestions?userId=<other>Un GUID ajeno sigue pasando por GetUserId y devuelve 403 para un no administrador. Probado en laboratorio (impersonate-403=yes)
ReconGET /Users/{userId}/Suggestions heredadoSe requiere el GUID de la ruta, por lo que sí llama a GetUserId
IntegridadPOST /Users/Password?userId=AssertCanUpdateUser
IntegridadPOST /Users/{id}/PolicyRequiresElevation
Integridaddispositivos, sesiones, AddAdditionalUsersolo elevación o sesión propia
ReconGET /Users / GET /Users/{id}UserDto + política (GUIDs de carpeta, bit de administrador), no contenidos de biblioteca ni hashes. Enumeración del hogar, no este residuo

No estoy afirmando RCE mediante DLL de plugin, una reverse shell ni robo de contraseñas. El volcado es el catálogo (y la ruta) de bibliotecas a las que el llamador no estaba asignado. El seguimiento de stream por GUID es un comportamiento de larga data de Jellyfin HTML5/DLNA; este residuo es lo que enumera los IDs.

Cómo lo encontré

v12.2 cerró la oleada de GHSA de 12.0. Aun así me quedé en esa etiqueta y leí cada consulta userId junto a RequestHelpers.GetUserId. Items siempre lo usa. Suggestions se ramifica: userId vacío -> user = null, nunca GetUserId. Ese es el residuo.

run.sh siembra dos bibliotecas de películas (PrivateA nombrada con el testigo, PublicB), completa el asistente, crea labuser con EnableAllFolders=false y solo EnabledFolders=PublicB, luego compara GET /Items contra GET /Items/Suggestions.

Falsos caminos ya registrados: tratar GET /Items como la fuga (está con ámbito); tratar Suggestions?userId=<admin> como la fuga (403); tratar la ruta heredada /Users/{userId}/Suggestions como el agujero (tiene un GUID, así que llama a GetUserId); afirmar que el stream sin autenticación es el fallo de este paquete (residuo hermano); una reverse shell. Teatro.

Descargar herramienta