
Advisory di sicurezza: il portale per sviluppatori di Azure APIM consente la registrazione di account cross-tenant aggirando le restrizioni di iscrizione dell'interfaccia utente. Segnalato due volte a MSRC - chiuso come "by design".
Stato (01.12.2025): Questa vulnerabilità è ancora attiva e sfruttabile. Microsoft non ha corretto il problema e lo considera "by design".
Una vulnerabilità di sicurezza nel portale per sviluppatori (Developer Portal) di Azure API Management (APIM) consente agli attaccanti di registrare account su qualsiasi istanza APIM che abbia l'autenticazione di base (Basic Authentication) abilitata, anche quando gli amministratori hanno disabilitato la registrazione degli utenti nell'interfaccia del portale.
Questo bypass consente la creazione di account cross-tenant, permettendo potenzialmente l'accesso non autorizzato alla documentazione delle API, alle chiavi di sottoscrizione e ad altre risorse esposte tramite il portale per sviluppatori.
| Data | Azione |
|---|---|
| 2025-09-30 | Vulnerabilità scoperta |
| 2025-09-30 | Primo report inviato a MSRC |
| 2025-10-30 | Risposta MSRC: chiuso come "non è una vulnerabilità" |
| 2025-11-01 | Secondo report inviato a MSRC con dettagli aggiuntivi |
| 2025-11-20 | Risposta MSRC: chiuso come "by design" |
| 2025-11-20 | Segnalato a CERT-FI |
| 2025-11-26 | Divulgazione pubblica |
| 2025-11-27 | CVE richiesto a MITRE |
| 2026-07-09 | CVE-2025-66390 assegnato da MITRE TL-Root/CNA-LR |
Quando Azure APIM è configurato con l'autenticazione di base per il portale per sviluppatori, gli amministratori possono disabilitare la registrazione degli utenti tramite l'interfaccia del portale Azure. Tuttavia, questo nasconde solo il modulo di registrazione nell'interfaccia del portale.
L'endpoint API di registrazione sottostante rimane attivo e accetta direttamente le richieste di registrazione, aggirando completamente la restrizione dell'interfaccia.
Due problemi si combinano per creare questa vulnerabilità:
L'attacco richiede due istanze APIM:
Passaggi:
Host dalla propria istanza a quella targetDettaglio tecnico chiave: il bypass cross-tenant funziona manipolando l'header Host nella richiesta POST di registrazione. L'endpoint /signup elabora le richieste in base all'header Host senza validare i confini di tenant.
Esempio di manipolazione della richiesta:
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]",...}}
Il problema principale: disabilitare la registrazione nell'interfaccia non disabilita l'API sottostante. L'endpoint API accetta richieste cross-tenant in base all'header Host.
La tua istanza APIM è vulnerabile se:
La tua istanza APIM NON è vulnerabile se:
Punto chiave: disabilitare la registrazione nell'interfaccia del portale Azure NON è sufficiente. Il provider di identità con autenticazione di base deve essere completamente rimosso per prevenire il bypass della registrazione cross-tenant.
Usa questi valori di proprietà per identificare le istanze APIM vulnerabili tramite Azure Resource Graph, modelli ARM o Azure Policy.
Il provider di identità con autenticazione di base è una risorsa separata all'interno dell'istanza APIM:
Resource Type: Microsoft.ApiManagement/service/identityProviders
Name: basic
Vulnerabile se presente: la presenza di una risorsa provider di identità basic indica che l'autenticazione di base è configurata.
Resource Type: Microsoft.ApiManagement/service/portalsettings/signup
Property: properties.enabled
| Proprietà | Valore | Significato |
|---|---|---|
properties.enabled | true | Registrazione visibile nell'interfaccia |
properties.enabled | false | Registrazione nascosta nell'interfaccia (l'API funziona ancora se l'autenticazione di base è presente!) |
Usa questa query per trovare istanze APIM potenzialmente vulnerabili:
resources
| where type == "microsoft.apimanagement/service"
| where properties.developerPortalStatus == "Enabled"
| where sku.name != "Consumption"
| project name, resourceGroup, subscriptionId, location, sku.name, properties.developerPortalStatus
Per verificare i provider di identità con autenticazione di base:
resources
| where type == "microsoft.apimanagement/service/identityproviders"
| where name endswith "/basic"
| project apimInstance=tostring(split(id, "/providers/Microsoft.ApiManagement/service/")[1]), resourceGroup, subscriptionId
Verifica lo stato del portale per sviluppatori:
az apim show --name <apim-name> --resource-group <rg-name> --query "{name:name, portalStatus:developerPortalStatus, sku:sku.name}"
Elenca i provider di identità (verifica la presenza di 'basic'):
az apim identity-provider list --resource-group <rg-name> --service-name <apim-name> --query "[].name"
Verifica le impostazioni di registrazione:
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"
Combinazione critica: un'istanza è vulnerabile al bypass della registrazione quando:
properties.developerPortalStatus == 'Enabled' EidentityProviders/basic esiste Eportalsettings/signup.properties.enabled == falseDICHIARAZIONE LEGALE: le informazioni seguenti sono fornite esclusivamente per identificare e proteggere le istanze APIM Azure della propria organizzazione. L'accesso non autorizzato a sistemi informatici è illegale. Testa solo sistemi di tua proprietà o per cui disponi di un'esplicita autorizzazione scritta.
Trova portali con registrazione tramite autenticazione di base (molto probabilmente vulnerabili):
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"
Trova portali con pagine di accesso (indica che l'autenticazione di base potrebbe essere configurata):
site:developer.azure-api.net "Sign in" "Email" "Password" -"Azure AD" -"Microsoft account"
site:developer.azure-api.net inurl:/signin "password"
Trova portali per sviluppatori con documentazione API esposta:
site:developer.azure-api.net inurl:/apis "Subscribe"
site:developer.azure-api.net "API" "Products" "Subscribe"
Individuazione generale:
site:*.developer.azure-api.net
inurl:developer.azure-api.net "Developer Portal"
Trova portali per sviluppatori APIM:
http.title:"Developer Portal" http.html:"azure-api.net"
ssl.cert.subject.cn:"*.developer.azure-api.net"
http.html:"developerPortal" http.html:"azure"
Dopo aver individuato i target, esegui la scansione con 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 la tua organizzazione usa Azure APIM, puoi identificare le tue istanze usando:
Portale Azure:
Azure CLI (per le tue sottoscrizioni):
# List all APIM instances in your subscriptions
az apim list --query "[].{name:name, resourceGroup:resourceGroup, url:developerPortalUrl}"
Usa questi metodi per verificare se le istanze APIM della TUA organizzazione sono vulnerabili:
Usando lo script di verifica:
# 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 Nuclei per audit di sicurezza interni:
# Scan your organization's APIM instances
nuclei -t azure-apim-signup-bypass.yaml -u https://YOUR-ORG.developer.azure-api.net
Quando esegui l'audit delle tue istanze, cerca:
Indicatori di NON vulnerabilità:
Se sei un professionista della sicurezza che svolge test autorizzati:
Se scopri un'istanza APIM di terze parti vulnerabile:
Viene fornito uno script Python per verificare se la tua istanza APIM è vulnerabile.
# Basic installation (HTTP probe only)
pip install requests colorama
# Full installation (includes Azure RM property checks)
pip install requests colorama azure-identity
Lo script supporta due modalità:
# 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
Quando si usa la modalità --azure, lo script interroga direttamente l'API Azure Resource Manager per verificare:
| Proprietà |
|---|
Prerequisiti per la modalità 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
Viene fornito un template Nuclei per la scansione automatizzata.
# 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 con dati captcha di testIl Microsoft Security Response Center (MSRC) è stato informato due volte di questa vulnerabilità. Entrambi i report sono stati chiusi con la seguente determinazione:
"By design"
MSRC non considera questa una vulnerabilità di sicurezza nonostante il bypass dei controlli amministrativi e le implicazioni cross-tenant.
apim_vuln_checker.py - script Python di verifica della vulnerabilitàazure-apim-signup-bypass.yaml - template Nuclei per la scansione automatizzataREADME.md - questo fileMihalis Haatainen
Bountyy Oy - azienda finlandese di penetration testing e ricerca sulla sicurezza
Questo advisory e gli strumenti associati sono rilasciati per scopi difensivi. Usali in modo responsabile.
Licenza MIT - Vedi il file LICENSE per i dettagli.
| Percorso proprietà | Valore vulnerabile | Descrizione |
|---|
properties.developerPortalStatus | Enabled | Il portale per sviluppatori è accessibile |
sku.name | Developer, Basic, Standard, Premium | Livelli non-Consumption (il livello Consumption ha funzionalità del portale limitate) |
| Condizione | Proprietà/Risorsa | Valore vulnerabile |
|---|
| Portale abilitato | properties.developerPortalStatus | == 'Enabled' |
| SKU non-Consumption | sku.name | != 'Consumption' |
| Autenticazione di base presente | risorsa identityProviders/basic | La risorsa esiste |
| Registrazione nascosta (bypass possibile) | portalsettings/signup.properties.enabled | == false (con autenticazione di base) |
| Valore vulnerabile |
|---|
properties.developerPortalStatus | == 'Enabled' |
sku.name | != 'Consumption' |
risorsa identityProviders/basic | Esiste |
portalsettings/signup.properties.enabled | == false |