Skip to content
KitploitKITPLOIT
StrumentiExploitsBlog
Log in
Invia
StrumentiExploitsBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

FeedContattoPrivacy© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
jellyfin-suggestions-idor — Jellyfin Server 12.2 - Alta - Remota - IDOR - GET /Items/Suggestions omit-userId espone il percorso e gli ID della libreria nascosta | Kitploit
Strumenti/GitHubGitHub/abraxas/jellyfin-suggestions-idor
Analisi delle VulnerabilitàSfruttamento di Applicazioni WebRaccolta InformazioniSicurezza WebPenetration TestingSicurezza delle APILab e Pratica
GitHub
abraxas/jellyfin-suggestions-idor

jellyfin-suggestions-idor

Jellyfin Server 12.2 - Alta - Remota - IDOR - GET /Items/Suggestions omit-userId espone il percorso e gli ID della libreria nascosta

Vedi Repository
11 giorno faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

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

Classe: IDOR. Portata: Remota (qualsiasi utente autenticato non amministratore).

GET /Items/Suggestions è protetto solo da [Authorize]. Quando userId viene omesso, SuggestionsController.GetSuggestions imposta user = null e non chiama mai RequestHelpers.GetUserId. InternalItemsQuery(null) non esegue SetUser. LibraryManager.GetItemsResult salta AddUserToQuery. new DtoOptions() include ItemFields.Path. GetBaseItemDtos(..., user: null) salta IsVisible.

GHSA-9x85 ha introdotto GetUserId (se omesso ricade sui claims; un GUID estraneo restituisce 403). ItemsController.GetItems lo usa sempre. Suggestions no. Il legacy GET /Users/{userId}/Suggestions ha sempre un GUID nella route, quindi quella variante passa effettivamente da GetUserId.

Un account con restrizioni estrae titoli, ID, panoramiche, ID dei provider e Path del filesystem per librerie a cui non è assegnato. Quei GUID funzionano su GET /Videos/{id}/stream non autenticato.

IDnessuna CVE al momento
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
ProdottoJellyfin Server
Affettov12.2 (ca0f16eb7c195f720a1493ed469a27c4657db0c6), immagine jellyfin/jellyfin:12.2
Authautenticato (qualsiasi non amministratore, incluso un account bambino / libreria nascosta)
LicenzaGNU Affero GPL v3.0
Labsolo 127.0.0.1:18790

Residuo #1 di Jellyfin 12.2 leftovers. Stessa versione, altri pacchetti: jellyfin-svg-gzip (residuo GHSA-cf3c gzip data:image/png), jellyfin-playlist-itemids (residuo GHSA-9x85 ItemIds + stream non autenticato), jellyfin-ffmpeg-colonslash (residuo GHSA-wwwm virgolette URL .strm). Questo pacchetto è quello che estrae la libreria nascosta.

Cosa può fare un attaccante

Qualsiasi utente autenticato non amministratore, incluso un account bambino / libreria nascosta / MaxParentalRating. Serve un normale token utente. Nessun amministratore, nessuna API key. Non cambiano le password. Non creano amministratori. Inventariano librerie a cui non sono stati assegnati, incluso il Path del filesystem, poi riproducono quei GUID.

Tabella dei privilegi (esaustiva). Stesso criterio di Signal-Server Dropwizard admin: metodo + percorso, cosa concede quella chiamata, ricognizione vs integrità vs disponibilità, dimostrato in lab vs dedotto, superficie adiacente che resta chiusa.

AsseMetodo + percorsoConcedeProvenienza
ReconGET /Items/Suggestions senza userId (opzionali limit / mediaType / type)Elenco ricorsivo di item non limitato all'ambito: Name, Id, Overview, ID dei provider, percorso filesystem, metadati delle immagini di librerie non assegnate al chiamante, incluse cartelle assegnate solo a un utente nascosto. ACL delle cartelle, classificazione per età e tag consentiti non vengono applicati.Dimostrato in laboratorio. labuser limitato (EnableAllFolders=false, solo EnabledFolders=PublicB): GET /Items witness=0; Suggestions witness=1
ReconLo stesso con limit omessoInternalItemsQuery.Limit resta non impostato; il repository restituisce l'intero insieme di corrispondenze (l'intera tabella degli item, in ordine casuale)Sorgente (SuggestionsController.cs:70-95)
ReconGET /Videos/{itemId}/stream non autenticato con un GUID da quell'elencoByte di quel file con l'UID jellyfinSorgente (VideosController non ha [Authorize] a livello di classe; StreamingHelpers GetItemById senza un utente). Lo streaming è stato dimostrato in laboratorio nel residuato affine jellyfin-playlist-itemids, non in questo pacchetto
Integritànessuna su SuggestionsNessuna scrittura di password, policy, preferiti o sessioneChiuso
Disponibilitànessuna su SuggestionsNessun DoS oltre al normale costo della queryChiuso

Resta chiuso su questo pin

AsseMetodo + percorsoPerché è chiuso
ReconGET /Items?userId= e GET /Items?parentId=<hiddenFolder>Sempre GetUserId + IsVisible (ItemsController.cs:265, 342-350)
ReconGET /Playlists/{id}/Items?userId=GetUserId (PlaylistsController.cs:524). Classe GHSA-9x85, corretta
ReconGET /Items/Suggestions?userId=<other>Un GUID estraneo passa comunque per GetUserId e restituisce 403 per un non-admin. Dimostrato in laboratorio (impersonate-403=yes)
ReconGET /Users/{userId}/Suggestions legacyIl GUID nella route è obbligatorio, quindi chiama GetUserId
IntegritàPOST /Users/Password?userId=AssertCanUpdateUser
IntegritàPOST /Users/{id}/PolicyRequiresElevation
Integritàdispositivi, sessioni, AddAdditionalUsersolo elevazione o sessione propria
ReconGET /Users / GET /Users/{id}UserDto + policy (GUID delle cartelle, bit admin), non contenuti delle librerie o hash. Enumerazione dell'household, non questo residuato

Non sto rivendicando RCE tramite DLL di plugin, una reverse shell o il furto di password. Il dump è il catalogo (e il Path) delle librerie non assegnate al chiamante. Il seguito dello streaming tramite GUID è un comportamento di lunga data di Jellyfin HTML5/DLNA; questo residuato è ciò che enumera gli ID.

Come l'ho trovato

La v12.2 ha chiuso l'ondata di GHSA della 12.0. Mi sono comunque fermato su quel tag e ho letto ogni query userId accanto a RequestHelpers.GetUserId. Items la usa sempre. Suggestions si dirama: userId vuoto -> user = null, mai GetUserId. Questo è il residuato.

run.sh prepara due librerie di film (PrivateA con il witness nel nome, PublicB), completa la procedura guidata, crea labuser con EnableAllFolders=false e solo EnabledFolders=PublicB, poi confronta GET /Items con GET /Items/Suggestions.

Vicoli ciechi già registrati: considerare GET /Items come la fuga (è limitato all'ambito); considerare Suggestions?userId=<admin> come la fuga (403); considerare la route legacy /Users/{userId}/Suggestions come la falla (ha un GUID quindi chiama GetUserId); dichiarare lo streaming non autenticato come bug di questo pacchetto (residuato affine); una reverse shell. Teatro.

Scarica lo strumento