
Write-up e prova de conceito para CVE-2026-94609, uma falha de escalonamento de privilégios no authentik que permite a usuários com add_user_to_group ingressar em grupos de superusuário por meio da Groups API.
Análise e prova de conceito de uma vulnerabilidade de escalação de privilégios no goauthentik/authentik, corrigida nas versões 2026.2.7 / 2026.5.7 / 2026.8.2 e designada CVE-2026-94609 (GHSA-h6c5-mpvq-j4jc).
Fui um dos pesquisadores creditados neste aviso (
@anthonyk2923— crédito aceito). Este repositório documenta o caminho de código específico que encontrei e reportei de forma independente, além de um PoC. O aviso publicado cobre o problema completo e mais amplo (hierarquia de grupos + atribuição de papéis), que foi reportado por múltiplos pesquisadores independentes e corrigido em conjunto.
Uma conta com apenas uma permissão rotineira e comumente delegada —
authentik_core.add_user_to_group (adicionar membros a um grupo) — podia adicionar
a si mesma ou qualquer outro usuário diretamente em um grupo existente marcado
como is_superuser=True através da API padrão de Grupos, e esse usuário imediatamente
se tornava um superusuário real do authentik. Isso acontecia sem nunca possuir
authentik_core.enable_group_superuser, a permissão especificamente projetada
para controlar exatamente essa ação.
O authentik já havia corrigido a versão espelhada desse bug no lado do Usuário (atribuir grupos de superusuário a um usuário). A verificação equivalente estava ausente no lado do Grupo (atribuir usuários a um grupo de superusuário).
O authentik modela duas permissões RBAC intencionalmente separadas para o gerenciamento de membros de grupos:
authentik_core.add_user_to_group — destinada ao gerenciamento rotineiro e delegado
de membros (por exemplo, um papel de "helpdesk" ou "líder de equipe" que gerencia
as listas cotidianas da equipe).authentik_core.enable_group_superuser — destinada a controlar o ato muito mais
sensível de conceder ou ingressar em um grupo cuja flag is_superuser=True
torna cada membro um superusuário completo do authentik.A separação existe justamente para que uma organização possa delegar amplamente o gerenciamento comum de grupos, sem também conceder a capacidade de criar superusuários.
O authentik já havia corrigido exatamente essa confusão uma vez, no lado do Usuário
da relação (PATCH /api/v3/core/users/{pk}/ via
UserSerializer.validate_groups()), rastreado como
GHSA-h6x7-hjjc-wjc9 / CVE-2026-40172
(CVSS 8.1, Alta). A correção adicionou:
# authentik/core/api/users.py (fixed)
def validate_groups(self, groups: list) -> list:
"""Require enable_group_superuser permission when adding a user to a superuser group."""
...
for group in groups:
if not group.is_superuser:
continue
if group in current_groups:
continue
if not request.user.has_perm("authentik_core.enable_group_superuser"):
raise ValidationError(...)
O caminho de código simétrico no lado do Grupo — adicionar membros a um grupo, em vez de adicionar grupos a um usuário — nunca recebeu a verificação equivalente.
GroupSerializer.validate_users() em authentik/core/api/groups.py apenas
verificava add_user_to_group, e nunca inspecionava self.instance.is_superuser
de forma alguma:
# authentik/core/api/groups.py (vulnerable)
def validate_users(self, users: list) -> list:
"""Require add_user_to_group permission when adding new members via group PATCH."""
request: Request = self.context.get("request", None)
if not request:
return users
if not self.instance:
return users
current_user_pks = set(self.instance.users.values_list("pk", flat=True))
new_users = [u for u in users if u not in current_user_pks]
if not new_users:
return users
has_perm = request.user.has_perm(
"authentik_core.add_user_to_group"
) or request.user.has_perm("authentik_core.add_user_to_group", self.instance)
if not has_perm:
raise ValidationError(_("User does not have permission to add members to this group."))
return users
Não há nenhuma proteção if self.instance.is_superuser: require enable_group_superuser
em lugar algum deste método. Como resultado:
Qualquer chamador que possua
add_user_to_group— seja globalmente, seja com escopo de objeto em apenas um grupo de superusuário específico — pode fazerPATCHno campousersdesse grupo para adicionar qualquer usuário (incluindo a si mesmo), e esse usuário se torna um superusuário real do authentik imediatamente.
add_user_to_group é exatamente o tipo de permissão que o próprio modelo RBAC
de granularidade fina do authentik incentiva delegar amplamente e independentemente de
enable_group_superuser — por exemplo, para um papel personalizado de "gerente de usuários" ou "helpdesk".
O teste existente
authentik/core/tests/test_groups_api.py::test_patch_users_with_global_perm
já demonstrava que uma concessão global de add_user_to_group (sem
escopo de objeto algum) é suficiente para fazer PATCH de membros em qualquer grupo da
instância — esse teste simplesmente nunca exercitou um grupo com
is_superuser=True, então a lacuna passou despercebida.
Esta é a mesma falha subjacente que o aviso publicado descreve de forma mais ampla: os grupos formam uma hierarquia e o status de superusuário é herdado de qualquer grupo pai, mas as verificações que controlam quem pode alterar a associação de membros de um grupo, a parentalidade de grupos e a atribuição de papéis ou não verificavam o status de superusuário de forma alguma, ou apenas olhavam a flag do próprio grupo em vez da efetiva (herdada).
Escalação de privilégios completa de "qualquer conta que possua uma permissão rotineira e comumente delegada de associação a grupos" para "superusuário completo do authentik" — que controla cada tenant, o SSO de cada aplicação downstream, todas as contas de usuário, todos os segredos/certificados gerenciados pelo authentik e toda a configuração da instância.
CVE-2026-94609.py
Um PoC autônomo no estilo de cliente HTTP ao vivo. Ele recebe uma URL alvo e um token de API
para uma conta de baixo privilégio (possuindo apenas add_user_to_group), e
opcionalmente um grupo alvo/vítima, então tenta a mesma escalação através
da API real:
# Check your own deployment for the bug, no mutation:
python3 exploit_CVE-2026-94609.py --url https://authentik.example.com \
--token <low-priv-api-token> --group "superadmins" --check-only
# List superuser groups reachable to this token:
python3 exploit_CVE-2026-94609.py --url https://authentik.example.com \
--token <low-priv-api-token> --list-groups
# Attempt the actual escalation (self, or a named/PK victim):
python3 exploit_CVE-2026-94609.py --url https://authentik.example.com \
--token <low-priv-api-token> --group "superadmins" --victim jdoe
Requer apenas pip install requests. Apenas para uso autorizado — execute isto
contra instâncias que você está explicitamente autorizado a testar.
| Branch | Afetadas | Corrigidas |
|---|---|---|
| 2026.2.x | ≤ 2026.2.6 | 2026.2.7 |
| 2026.5.x | ≤ 2026.5.6 | 2026.5.7 |
| 2026.8.x | ≤ 2026.8.1 | 2026.8.2 |
Atualize para uma versão corrigida. Se você não puder atualizar imediatamente, conforme a solução alternativa do aviso oficial: restrinja as permissões para criar/modificar grupos, modificar usuários e adicionar usuários a grupos de modo que apenas administradores completos as possuam — não delegue nenhuma delas a papéis não administrativos até que esteja corrigido.
Esta análise e o PoC são fornecidos para fins educacionais e de pesquisa em segurança defensiva. Consulte a licença do próprio authentik (MIT) para o projeto subjacente.
| Classe da vulnerabilidade | Escalação de Privilégios / Controle de Acesso Inadequado |
| CWE | CWE-269 (Gerenciamento Inadequado de Privilégios), CWE-863 (Autorização Incorreta) |
| CVSS 3.1 | AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H — Alta |
| Afetadas | authentik ≤ 2026.2.6, ≤ 2026.5.6, ≤ 2026.8.1 |
| Corrigido em | 2026.2.7, 2026.5.7, 2026.8.2 |
| Rota acessível | PATCH /api/v3/core/groups/{group_uuid}/ |
| Causa raiz | GroupSerializer.validate_users() nunca verificava enable_group_superuser |