Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

FluxContactConfidentialité© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
jellyfin-playlist-itemids — Jellyfin Server 12.2 - Élevée - Distant - IDOR - ItemIds de playlist publique restants de GHSA-9x85 puis diffusion non authentifiée | Kitploit
Outils/GitHubGitHub/abraxas/jellyfin-playlist-itemids
Analyse des VulnérabilitésExploitation d'Applications WebExfiltration de DonnéesCollecte d'InformationsSécurité WebTests d'IntrusionSécurité des APILabs et Pratique
GitHubabraxas/jellyfin-playlist-itemids

jellyfin-playlist-itemids

Jellyfin Server 12.2 - Élevée - Distant - IDOR - ItemIds de playlist publique restants de GHSA-9x85 puis diffusion non authentifiée

Voir le dépôt
3il y a 1 jourPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

Abraxas Labs - jellyfin-playlist-itemids

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

jellyfin-playlist-itemids

Classe : IDOR Portée : Distante (tout utilisateur pouvant voir une playlist publique)

Jellyfin Server v12.2 (ca0f16eb7c195f720a1493ed469a27c4657db0c6) - Jellyfin

GHSA-9x85 a corrigé GET /Playlists/{id}/Items avec GetUserId plus Where(i => i.Item2.IsVisible(user)). GET /Playlists/{id} n'a pas reçu ce filtre. ItemIds correspond à GetManageableItems() sans IsVisible sur les enfants. GetPlaylistForUser exige seulement que la playlist soit visible.

CreatePlaylistDto.IsPublic vaut true par défaut. Les playlists OpenAccess sont IsVisible pour les autres utilisateurs (HasParentalAllowedChild permet toujours à un second utilisateur de voir la playlist). GET /Videos/{id}/stream sans authentification n'a pas de [Authorize]. StreamingHelpers charge GetItemById sans utilisateur.

Un utilisateur qui peut voir une playlist publique lit les GUID des enfants privés depuis ItemIds, puis diffuse les fichiers sans jeton.

IDpas encore de CVE
ClasseIDOR (ItemIds de playlist, résidu de GHSA-9x85, puis diffusion sans authentification)
PortéeDistante (tout utilisateur pouvant voir une playlist publique)
CWECWE-639, CWE-862
CVSSÉlevé : 6.5 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
ProduitJellyfin Server
Affectév12.2 (ca0f16eb) image jellyfin/jellyfin:12.2
Authauthentifié pour le GET de la playlist ; aucun pour le flux
LicenceGNU Affero GPL v3.0
Lab127.0.0.1:18800 uniquement

Résidu #3 de Jellyfin 12.2 leftovers. Résidu #1 (le plus important) : jellyfin-suggestions-idor. Même version épinglée : jellyfin-svg-gzip · jellyfin-ffmpeg-colonslash.

Ce qu'un attaquant peut faire

La victime et l'attaquant sont deux utilisateurs sur un même serveur avec des bibliothèques disjointes (enfants vs adultes, ou un dossier masqué). La victime place un film privé sur une playlist publique. La création par corps avec IsPublic vaut true par défaut, c'est donc le cas habituel, pas un partage. L'attaquant se connecte avec un compte restreint, lit l'objet playlist, puis récupère le fichier sans en-tête Authorization.

Il s'agit des GUID de médias dans des bibliothèques non attribuées à l'attaquant, puis du fichier complet via le flux. Ce n'est pas de l'énumération de titres de playlists. L'ajout/création écarte toujours les éléments non visibles.

Reconnaissance (prouvé en lab)

MéthodeCheminPrivilège
GET/Playlists/{playlistId}GUID des enfants d'une playlist visible (ItemIds issu de GetManageableItems(), sans IsVisible sur les enfants). Aussi Shares[].UserId / CanEdit (userId des destinataires du partage). Lab : le GET /Playlists/{id}/Items de B est vide ; le GET /Playlists/{id} du même id liste le GUID privé a2bf95146e44897be6fb09020a82eb52.

GetPlaylistForUser exige seulement que la playlist elle-même soit visible. OpenAccess plus HasParentalAllowedChild (qui contourne la vérification des tags autorisés) suffit. La route Items corrigée sert de contrôle : elle filtre toujours.

Confidentialité (prouvé en lab)

MéthodeCheminPrivilège
GET/Videos/{itemId}/stream?static=trueOctets de média privé. Pas de [Authorize]. StreamingHelpers fait GetItemById<BaseItem>(id) sans utilisateur. Lab : 200 sans auth, 1142 octets, témoin JELLYFIN-PLAYLIST-ITEMIDS-WITNESS dans le corps.
GET/Audio/{itemId}/streamMême puits pour l'audio. Même helper, même recherche non délimitée.

Le HLS authentifié GET /Videos/{itemId}/master.m3u8 emprunte le même chemin GetItemById (DynamicHlsController a [Authorize] au niveau de la classe). Le lab a exercé le flux progressif non authentifié, pas le HLS.

Intégrité (fermé)

MéthodeCheminPrivilège
POST/Playlists/{id}/Items et création de IdsFermé. Playlist.GetPlaylistItems exécute IsVisible. Les GUID privés sont écartés, pas liés.

Surface adjacente qui reste fermée

  • Ajout de GUID privés à sa propre playlist.
  • InstantMix (GetItemById(id, user) limité à l'utilisateur).
  • Collections (EnableCollectionManagement par défaut à false ; FilterLinkedChildrenPerUser).
  • Préfixe de transcodage GHSA-hw73 (ValidateTranscodePath maintient les segments HLS hérités à l'intérieur du répertoire de transcodage).
  • Usurpation de userId GHSA-9x85 sur Items (GetUserId renvoie 403 pour un id étranger).
  • Listage GET /Playlists/{id}/Items des enfants privés (la route corrigée ; lab items-filtered=yes).

Aucune écriture de mot de passe/politique. Aucune installation de plugin. Aucun shell.

L'ACL de dossier (EnabledFolders) seule n'a pas masqué l'enfant sur /Items dans ce lab. AllowedTags=["lab-public"] a fait que IsVisible l'écarte. ItemIds et le flux non authentifié ne consultent pas ce filtre.

Comment je l'ai trouvé

J'ai épinglé jellyfin/jellyfin v12.2 (ca0f16eb). Vingt recherches dans le code source sur les résidus de la vague GHSA 12.0. GHSA-9x85 a appris à GetPlaylistItems à filtrer les enfants. Je me suis demandé si GetPlaylist avait reçu le même Where. Ce n'était pas le cas. Les endpoints de flux n'ont jamais reçu de GetItemById limité à l'utilisateur.

Fausse piste : traiter EnabledFolders comme le masquage des Items. IsVisible d'un film relève du contrôle parental/des tags, pas de l'ACL de dossier. Le lab a dû définir AllowedTags pour que la route Items corrigée devienne vide. C'est le contrôle. Le résidu ne l'utilise pas.

Lab

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

Ou :

cd lab
./run.sh

Cibler uniquement http://127.0.0.1:18800. Image jellyfin/jellyfin:12.2. run.sh initialise deux minuscules mp4 (PrivateA comme nom de fichier témoin, PublicB factice). L'assistant crée labadmin, les deux dossiers, puis labuser avec EnableAllFolders=false, EnabledFolders=PublicB, AllowedTags=["lab-public"]. L'administrateur place le film privé dans une playlist publique. Loopback. Témoin uniquement. Nécessite Docker et ffmpeg pour l'initialisation.

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
Télécharger l’outil