CVE-2026-103956 - Loom para AWS - Crítico - Bypass de autenticação - super-admin não autenticado quando nenhum IdP está configurado
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · cve-2026-103956-loom-unauth
Loom for AWS < 1.6.1 - AWS Labs
Quando o Cognito não está configurado e nenhum IdP externo está ativo, get_current_user entrega a toda requisição t-admin / g-admins-super. Isso inclui requisições sem cabeçalho Authorization. Uma implantação nova antes da configuração do IdP é um painel de administração aberto.
| ID | CVE-2026-103956 |
| CWE | CWE-306 / CWE-1188 |
| CVSS | Crítico: 10.0 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H |
| Produto | Loom for AWS |
| Afetado | < 1.6.1. Fixação do laboratório v1.6.0 (8c658d61). Corrigido em v1.6.1 (ccad5665). |
| Autenticação | não autenticado |
| Licença | GNU Affero GPL v3.0 |
| Laboratório | somente 127.0.0.1 |
O atacante controla o plano de controle do agente sem nenhuma credencial.
GET /api/auth/me sem cabeçalho retorna username=local-dev, sub=local, grupos t-admin e g-admins-super. Todos os escopos em GROUP_SCOPES vêm com essa identidade.POST /api/mcp/servers não autenticado retorna 201. MCP, A2A, agentes, memórias, segurança, configurações, credenciais e auditoria de administração ficam atrás da mesma dependência.GET /api/mcp/servers/{id}/export é admin:write. Nesta fixação, retorna oauth2_client_secret do SQLite. O texto da CVE também menciona reescrita de política de função IAM em funções de agente gerenciadas; esse caminho exige AWS e está fora deste laboratório de loopback.A v1.6.1 exige LOOM_ALLOW_UNAUTHENTICATED_LOCAL_DEV mais um cliente de loopback. A mesma requisição retorna 401 (No identity provider configured).
A AWS publicou CVE-2026-103956 com GHSA-vgmj-998f-r8mp e o boletim 2026-124-AWS. Fixei awslabs/loom v1.6.0 (8c658d61) ao lado de v1.6.1 (ccad5665) e executei o backend em SQLite com LOOM_COGNITO_USER_POOL_ID não definido.
backend/app/dependencies/auth.py get_current_user verifica a variável de ambiente do Cognito e uma linha de IdP ativo. Ambas vazias: retorna UserInfo(sub="local", username="local-dev", groups=["t-admin", "g-admins-super"], scopes=ALL_SCOPES). O token nunca é lido.
Levantei o FastAPI padrão em loopback 127.0.0.1:18180 (v1.6.0) e 18181 (v1.6.1). Sem frontend. Sem AWS. GET /api/auth/me não autenticado na 1.6.0 retornou 200 com esses grupos. POST /api/mcp/servers não autenticado com oauth2_client_secret=CVE-2026-103956-WITNESS retornou 201. GET /api/mcp/servers/1/export devolveu o segredo. Na 1.6.1, o mesmo /api/auth/me retornou 401.
SUCCESS CVE-2026-103956 me-http=200 me-user=local-dev me-sub=local me-groups=t-admin,g-admins-super mcp-create=201 export-has-secret=yes list-has-witness=yes patched-me-http=401 CVE-2026-103956-WITNESS
Caminhos errados já registrados: public.ecr.aws/docker/library/python:3.13-slim foi ignorado em favor do Docker Hub python:3.13-slim; o primeiro /health na v1.6.0 foi curl 52 enquanto o uvicorn estava vinculado, depois 200; o esquema de criação do MCP correspondeu no primeiro POST, sem nova tentativa 422. Um reverse shell. Teatro. O oráculo é /api/auth/me mais o segredo exportado.
cd lab
./run.sh
Alvo somente http://127.0.0.1:18180 (v1.6.0) e http://127.0.0.1:18181 (v1.6.1). run.sh faz clone superficial dessas tags, compila ambos os backends e depois desmonta a pilha. SQLite. Sem variáveis de ambiente do Cognito. Sem LOOM_ALLOW_UNAUTHENTICATED_LOCAL_DEV no serviço corrigido.
Atualize para 1.6.1 ou posterior. A AWS recomenda 1.7.0 para os problemas irmãos de SSRF/token. O bypass da 1.6.1 é opt-in e somente loopback. Até então, conclua o Cognito ou um IdP externo antes que o backend seja alcançável além do loopback, e mantenha LOOM_ALLOW_UNAUTHENTICATED_LOCAL_DEV não definido em qualquer coisa implantada.
backend/app/dependencies/auth.py (get_current_user)