
Aviso de segurança: o Portal do Desenvolvedor do Azure APIM permite o registro de contas entre locatários ao contornar as restrições de inscrição da UI. Relatado ao MSRC duas vezes - encerrado como "by design".
Status (01/12/2025): Esta vulnerabilidade continua ativa e explorável. A Microsoft não corrigiu este problema e o considera "by design" (comportamento intencional).
Uma vulnerabilidade de segurança no Portal do Desenvolvedor do Azure API Management (APIM) permite que atacantes registrem contas em qualquer instância do APIM que tenha a Autenticação Básica habilitada, mesmo quando os administradores desabilitaram o cadastro de usuários na interface do portal.
Esse bypass permite a criação de contas entre locatários (cross-tenant), potencialmente permitindo acesso não autorizado à documentação de APIs, chaves de assinatura e outros recursos expostos por meio do Portal do Desenvolvedor.
| Data | Ação |
|---|---|
| 2025-09-30 | Vulnerabilidade descoberta |
| 2025-09-30 | Relatório inicial enviado ao MSRC |
| 2025-10-30 | Resposta do MSRC: Encerrado como "não é uma vulnerabilidade" |
| 2025-11-01 | Segundo relatório enviado ao MSRC com detalhes adicionais |
| 2025-11-20 | Resposta do MSRC: Encerrado como "by design" |
| 2025-11-20 | Relatado ao CERT-FI |
| 2025-11-26 | Divulgação pública |
| 2025-11-27 | CVE solicitado à MITRE |
| 2026-07-09 | CVE-2025-66390 atribuído pela MITRE TL-Root/CNA-LR |
Quando o Azure APIM está configurado com Autenticação Básica para o Portal do Desenvolvedor, os administradores podem desabilitar o registro de usuários pela interface do Portal Azure. No entanto, isso apenas oculta o formulário de cadastro na interface do portal.
O endpoint da API de cadastro subjacente permanece ativo e aceita solicitações de registro diretamente, contornando completamente a restrição da interface.
Dois problemas se combinam para criar esta vulnerabilidade:
O ataque requer duas instâncias de APIM:
Passos:
Host da sua instância para a instância alvoDetalhe técnico fundamental: O bypass entre locatários funciona manipulando o cabeçalho Host na solicitação POST de cadastro. O endpoint /signup processa solicitações com base no cabeçalho Host, sem validar os limites entre locatários.
Exemplo de manipulação da solicitação:
POST /signup HTTP/1.1
Host: target-apim.developer.azure-api.net <-- Changed from attacker's instance
Origin: https://attacker-apim.developer.azure-api.net
Content-Type: application/json
{"challenge":{...},"signupData":{"email":"[email protected]",...}}
O problema central: desabilitar o cadastro na interface não desabilita a API subjacente. O endpoint da API aceita solicitações entre locatários com base no cabeçalho Host.
Sua instância do APIM é vulnerável se:
Sua instância do APIM NÃO é vulnerável se:
Ponto-chave: Desabilitar o cadastro na interface do Portal Azure NÃO é suficiente. O provedor de identidade de Autenticação Básica deve ser completamente removido para impedir o bypass de cadastro entre locatários.
Use estes valores de propriedade para identificar instâncias vulneráveis do APIM por meio do Azure Resource Graph, modelos ARM ou Azure Policy.
O provedor de identidade de Autenticação Básica é um recurso separado dentro da instância do APIM:
Resource Type: Microsoft.ApiManagement/service/identityProviders
Name: basic
Vulnerável se existir: A presença de um recurso de provedor de identidade basic indica que a Autenticação Básica está configurada.
Resource Type: Microsoft.ApiManagement/service/portalsettings/signup
Property: properties.enabled
| Propriedade | Valor | Significado |
|---|---|---|
properties.enabled | true | Cadastro visível na interface |
properties.enabled | false | Cadastro oculto na interface (a API ainda funciona se a Autenticação Básica existir!) |
Use esta consulta para encontrar instâncias do APIM potencialmente vulneráveis:
resources
| where type == "microsoft.apimanagement/service"
| where properties.developerPortalStatus == "Enabled"
| where sku.name != "Consumption"
| project name, resourceGroup, subscriptionId, location, sku.name, properties.developerPortalStatus
Para verificar provedores de identidade de Autenticação Básica:
resources
| where type == "microsoft.apimanagement/service/identityproviders"
| where name endswith "/basic"
| project apimInstance=tostring(split(id, "/providers/Microsoft.ApiManagement/service/")[1]), resourceGroup, subscriptionId
Verifique o status do Portal do Desenvolvedor:
az apim show --name <apim-name> --resource-group <rg-name> --query "{name:name, portalStatus:developerPortalStatus, sku:sku.name}"
Liste os provedores de identidade (verifique se há 'basic'):
az apim identity-provider list --resource-group <rg-name> --service-name <apim-name> --query "[].name"
Verifique as configurações de cadastro:
az rest --method get --url "https://management.azure.com/subscriptions/<sub-id>/resourceGroups/<rg-name>/providers/Microsoft.ApiManagement/service/<apim-name>/portalsettings/signup?api-version=2022-08-01" --query "properties.enabled"
Combinação crítica: Uma instância é vulnerável ao bypass de cadastro quando:
properties.developerPortalStatus == 'Enabled' EidentityProviders/basic existe Eportalsettings/signup.properties.enabled == falseAVISO LEGAL: As informações abaixo são fornecidas exclusivamente para identificar e proteger as instâncias do Azure APIM da sua própria organização. O acesso não autorizado a sistemas de computador é ilegal. Teste apenas sistemas que você possui ou para os quais tenha autorização explícita por escrito.
Encontre portais com cadastro por Autenticação Básica (provavelmente vulneráveis):
site:developer.azure-api.net "Sign up" "Email" "Password"
site:developer.azure-api.net "Create account" "Username"
site:developer.azure-api.net inurl:/signup "register"
Encontre portais com páginas de login (indica que a Autenticação Básica pode estar configurada):
site:developer.azure-api.net "Sign in" "Email" "Password" -"Azure AD" -"Microsoft account"
site:developer.azure-api.net inurl:/signin "password"
Encontre portais do desenvolvedor com documentação de APIs exposta:
site:developer.azure-api.net inurl:/apis "Subscribe"
site:developer.azure-api.net "API" "Products" "Subscribe"
Descoberta geral:
site:*.developer.azure-api.net
inurl:developer.azure-api.net "Developer Portal"
Encontre Portais do Desenvolvedor do APIM:
http.title:"Developer Portal" http.html:"azure-api.net"
ssl.cert.subject.cn:"*.developer.azure-api.net"
http.html:"developerPortal" http.html:"azure"
Após descobrir os alvos, faça a varredura com o Nuclei:
# Save targets to file
echo "https://target1.developer.azure-api.net" > targets.txt
echo "https://target2.developer.azure-api.net" >> targets.txt
# Mass scan
nuclei -t azure-apim-signup-bypass.yaml -l targets.txt -o vulnerable.txt
Se sua organização usa o Azure APIM, você pode identificar suas próprias instâncias usando:
Portal Azure:
Azure CLI (para suas assinaturas):
# List all APIM instances in your subscriptions
az apim list --query "[].{name:name, resourceGroup:resourceGroup, url:developerPortalUrl}"
Use estes métodos para verificar se as instâncias do APIM da SUA organização são vulneráveis:
Usando o script de verificação:
# Check your own instance
python apim_vuln_checker.py https://YOUR-ORG.developer.azure-api.net
# With Azure RM property checks (recommended for internal audits)
python apim_vuln_checker.py --azure -s YOUR-SUB-ID -g YOUR-RG -n YOUR-APIM-NAME
Usando o Nuclei para auditorias internas de segurança:
# Scan your organization's APIM instances
nuclei -t azure-apim-signup-bypass.yaml -u https://YOUR-ORG.developer.azure-api.net
Ao auditar suas próprias instâncias, procure por:
Indicadores de NÃO vulnerabilidade:
Se você é um profissional de segurança realizando testes autorizados:
Se você descobrir uma instância vulnerável de APIM de terceiros:
Um script em Python é fornecido para verificar se a sua instância do APIM é vulnerável.
# Basic installation (HTTP probe only)
pip install requests colorama
# Full installation (includes Azure RM property checks)
pip install requests colorama azure-identity
O script suporta dois modos:
# HTTP probe (external check)
python apim_vuln_checker.py https://your-apim.developer.azure-api.net
# Azure RM property check (requires az login)
python apim_vuln_checker.py --azure -s <subscription-id> -g <resource-group> -n <apim-name>
# Combined check (both HTTP probe and Azure RM)
python apim_vuln_checker.py https://your-apim.developer.azure-api.net \
--azure -s <subscription-id> -g <resource-group> -n <apim-name>
# Verbose output
python apim_vuln_checker.py https://your-apim.developer.azure-api.net -v
# Skip SSL verification
python apim_vuln_checker.py https://your-apim.developer.azure-api.net -k
# JSON output
python apim_vuln_checker.py https://your-apim.developer.azure-api.net --json
Ao usar o modo --azure, o script consulta diretamente a API do Azure Resource Manager para verificar:
| Propriedade |
|---|
Pré-requisitos para o modo Azure RM:
azure-identity: pip install azure-identityaz login ___ __ ____
/ _ )___ __ _____ / /___ ____ __ / __ \__ __
/ _ / _ \/ // / _ \/ __/ // / // / / /_/ / // /
/____/\___/\_,_/_//_/\__/\_, /\_, / \____/\_, /
/___//___/ /___/
Author: Mihalis Haatainen, Bountyy Oy - www.bountyy.fi
======================================================================
Azure APIM Vulnerability Checker
Cross-Tenant Signup Bypass Detection
======================================================================
[?] Checking signup endpoint accessibility...
[i] Signup endpoint is accessible
[?] Checking if Basic Auth signup API is accessible...
[!] Basic Auth signup API ACTIVE (captcha validation)
[?] Checking if signup is hidden/disabled in UI...
[i] Signup page returns 404 (hidden in UI)
======================================================================
VULNERABILITY ASSESSMENT RESULTS
======================================================================
Target: https://example.developer.azure-api.net
Risk Level: CRITICAL - VULNERABLE TO SIGNUP BYPASS
Detailed Checks:
[!] signup_ui: Signup endpoint is accessible
[!] basic_auth_api: Basic Auth signup API ACTIVE (captcha validation)
[+] signup_ui_hidden: Signup page returns 404 (hidden in UI)
Recommendations:
CRITICAL: SIGNUP BYPASS VULNERABILITY CONFIRMED
The Basic Auth signup API is accessible even though UI hides signup.
Attackers can register accounts by calling the API directly.
Immediate actions:
1. DISABLE Basic Authentication in Azure Portal immediately
2. Audit all developer portal user accounts for unauthorized signups
3. Review user creation logs - check for API-based registrations
4. Implement Azure AD authentication only
Um template Nuclei é fornecido para varredura automatizada.
# Single target
nuclei -t azure-apim-signup-bypass.yaml -u https://target.developer.azure-api.net
# Multiple targets from file
nuclei -t azure-apim-signup-bypass.yaml -l targets.txt
# With proxy (for debugging)
nuclei -t azure-apim-signup-bypass.yaml -u https://target.developer.azure-api.net -proxy http://127.0.0.1:8080
# Skip SSL verification
nuclei -t azure-apim-signup-bypass.yaml -u https://target.developer.azure-api.net -insecure
/signup com dados de captcha de testeO Microsoft Security Response Center (MSRC) foi notificado duas vezes sobre esta vulnerabilidade. Ambos os relatórios foram encerrados com a seguinte determinação:
"By design"
O MSRC não considera esta uma vulnerabilidade de segurança, apesar do bypass de controles administrativos e das implicações entre locatários.
apim_vuln_checker.py - Script Python de verificação de vulnerabilidadeazure-apim-signup-bypass.yaml - Template Nuclei para varredura automatizadaREADME.md - Este arquivoMihalis Haatainen
Bountyy Oy - Empresa finlandesa de testes de penetração e pesquisa em segurança
Este aviso e as ferramentas associadas são publicados para fins defensivos. Use com responsabilidade.
Licença MIT - Consulte o arquivo LICENSE para obter detalhes.
| Caminho da Propriedade | Valor Vulnerável | Descrição |
|---|
properties.developerPortalStatus | Enabled | O Portal do Desenvolvedor está acessível |
sku.name | Developer, Basic, Standard, Premium | Camadas não-Consumption (a camada Consumption tem recursos limitados de portal) |
| Condição | Propriedade/Recurso | Valor Vulnerável |
|---|
| Portal habilitado | properties.developerPortalStatus | == 'Enabled' |
| SKU não-Consumption | sku.name | != 'Consumption' |
| Autenticação Básica existe | recurso identityProviders/basic | O recurso existe |
| Cadastro oculto (bypass possível) | portalsettings/signup.properties.enabled | == false (com Autenticação Básica) |
| Valor Vulnerável |
|---|
properties.developerPortalStatus | == 'Enabled' |
sku.name | != 'Consumption' |
recurso identityProviders/basic | Existe |
portalsettings/signup.properties.enabled | == false |