Skip to content
KitploitKITPLOIT
FerramentasExploitsBlog
Log in
Enviar
FerramentasExploitsBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

FeedsContatoPrivacidade© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
jellyfin-playlist-itemids — Jellyfin Server 12.2 - Alta - Remoto - IDOR - ItemIds de playlist pública remanescentes do GHSA-9x85 e então stream não autenticado | Kitploit
Ferramentas/GitHubGitHub/abraxas/jellyfin-playlist-itemids
Análise de VulnerabilidadesExploração de Aplicações WebExfiltração de DadosColeta de InformaçõesSegurança WebTestes de PenetraçãoSegurança de APILabs e Prática
GitHubabraxas/jellyfin-playlist-itemids

jellyfin-playlist-itemids

Jellyfin Server 12.2 - Alta - Remoto - IDOR - ItemIds de playlist pública remanescentes do GHSA-9x85 e então stream não autenticado

Ver Repositório
3há 1 diaAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

Abraxas Labs - jellyfin-playlist-itemids

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

jellyfin-playlist-itemids

Classe: IDOR Alcance: Remoto (qualquer usuário que consiga ver uma playlist pública)

Jellyfin Server v12.2 (ca0f16eb7c195f720a1493ed469a27c4657db0c6) - Jellyfin

GHSA-9x85 corrigiu GET /Playlists/{id}/Items com GetUserId mais Where(i => i.Item2.IsVisible(user)). GET /Playlists/{id} não recebeu esse filtro. ItemIds é GetManageableItems() sem IsVisible nos filhos. GetPlaylistForUser exige apenas a visibilidade da playlist.

CreatePlaylistDto.IsPublic tem como padrão true. Playlists OpenAccess são IsVisible para outros usuários (HasParentalAllowedChild ainda permite que um segundo usuário veja a playlist). GET /Videos/{id}/stream sem autenticação não tem [Authorize]. StreamingHelpers carrega GetItemById sem um usuário.

Um usuário que consegue ver uma playlist pública lê os GUIDs privados dos filhos a partir de ItemIds e então transmite os arquivos sem token.

IDainda sem CVE
ClasseIDOR (resíduo de ItemIds de playlist do GHSA-9x85, seguido de stream sem autenticação)
AlcanceRemoto (qualquer usuário que consiga ver uma playlist pública)
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
ProdutoJellyfin Server
Afetadov12.2 (ca0f16eb) imagem jellyfin/jellyfin:12.2
Autenticaçãoautenticado para o GET da playlist; nenhuma para o stream
LicençaGNU Affero GPL v3.0
Labapenas 127.0.0.1:18800

Resíduo #3 de Jellyfin 12.2 leftovers. Resíduo #1 (mais importante): jellyfin-suggestions-idor. Mesmo pin: jellyfin-svg-gzip · jellyfin-ffmpeg-colonslash.

O que um atacante pode fazer

Vítima e atacante são dois usuários em um mesmo servidor com bibliotecas disjuntas (crianças vs adultos, ou uma pasta oculta). A vítima coloca um filme privado em uma playlist pública. O IsPublic padrão na criação via body é true, então esse é o caso usual, não um compartilhamento. O atacante faz login como uma conta restrita, lê o objeto da playlist e então busca o arquivo sem cabeçalho Authorization.

Isto são GUIDs de mídia em bibliotecas às quais o atacante não está atribuído, e então o arquivo completo via stream. Não é enumeração de título de playlist. Adicionar/criar ainda descartam itens não visíveis.

Recon (comprovado em lab)

MétodoCaminhoPrivilégio
GET/Playlists/{playlistId}GUIDs dos filhos de uma playlist visível (ItemIds de GetManageableItems(), sem IsVisible nos filhos). Também Shares[].UserId / CanEdit (userIds de compartilhamento). Lab: GET /Playlists/{id}/Items de B vazio; GET /Playlists/{id} do mesmo id listou o GUID privado a2bf95146e44897be6fb09020a82eb52.

GetPlaylistForUser exige apenas que a própria playlist seja visível. OpenAccess mais HasParentalAllowedChild (que ignora a verificação de tag permitida) é suficiente. A rota Items corrigida é o controle: ela ainda filtra.

Confidencialidade (comprovado em lab)

MétodoCaminhoPrivilégio
GET/Videos/{itemId}/stream?static=trueBytes de mídia privada. Sem [Authorize]. StreamingHelpers faz GetItemById<BaseItem>(id) sem um usuário. Lab: 200 sem autenticação, 1142 bytes, testemunha JELLYFIN-PLAYLIST-ITEMIDS-WITNESS no corpo.
GET/Audio/{itemId}/streamMesmo destino para áudio. Mesmo helper, mesma consulta sem escopo.

O HLS autenticado GET /Videos/{itemId}/master.m3u8 é o mesmo caminho GetItemById (DynamicHlsController tem [Authorize] no nível da classe). O lab exercitou o stream progressivo sem autenticação, não o HLS.

Integridade (fechado)

MétodoCaminhoPrivilégio
POST/Playlists/{id}/Items e criar IdsFechado. Playlist.GetPlaylistItems executa IsVisible. GUIDs privados são descartados, não vinculados.

Superfície adjacente que permanece fechada

  • Adicionar GUIDs privados à sua própria playlist.
  • InstantMix (GetItemById(id, user) com escopo de usuário).
  • Collections (EnableCollectionManagement padrão false; FilterLinkedChildrenPerUser).
  • Prefixo de transcode GHSA-hw73 (ValidateTranscodePath mantém segmentos HLS legados dentro do diretório de transcode).
  • Personificação de userId GHSA-9x85 em Items (GetUserId retorna 403 para um id estrangeiro).
  • Listagem de GET /Playlists/{id}/Items de filhos privados (a rota corrigida; lab items-filtered=yes).

Nenhuma escrita de senha/política. Nenhuma instalação de plugin. Nenhum shell.

A ACL de pasta (EnabledFolders) sozinha não ocultou o filho em /Items neste lab. AllowedTags=["lab-public"] fez IsVisible descartá-lo. ItemIds e o stream sem autenticação não consultam esse filtro.

Como eu encontrei

Fixe a versão jellyfin/jellyfin v12.2 (ca0f16eb). Vinte buscas no código-fonte sobre sobras da onda GHSA 12.0. GHSA-9x85 ensinou GetPlaylistItems a filtrar filhos. Perguntei se GetPlaylist recebeu o mesmo Where. Não recebeu. Os endpoints de stream nunca receberam um GetItemById com escopo de usuário.

Caminho errado: tratar EnabledFolders como o ocultamento de Items. IsVisible de filme é parental/tags, não ACL de pasta. O lab teve que definir AllowedTags para que a rota Items corrigida ficasse vazia. Esse é o controle. A sobra não o utiliza.

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

Aponte apenas para http://127.0.0.1:18800. Imagem jellyfin/jellyfin:12.2. O run.sh semeia dois mp4 minúsculos (nome de arquivo testemunha PrivateA, manequim PublicB). O assistente cria labadmin, ambas as pastas, depois labuser com EnableAllFolders=false, EnabledFolders=PublicB, AllowedTags=["lab-public"]. O administrador coloca o filme privado em uma playlist pública. Loopback. Apenas testemunha. Requer Docker e ffmpeg para semear.

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

Reprodução: python3 jellyfin-playlist-itemids-Abraxas-Labs.py.

Correção

Baixar ferramenta