安全公告:Azure APIM 开发者门户可通过绕过 UI 注册限制实现跨租户账户注册。已两次上报 MSRC——均以“按设计(by design)”关闭。
状态(2025年12月1日): 该漏洞仍然存在且可被利用。Microsoft 尚未修复此问题,并认为其“设计使然”。
Azure API 管理(APIM)开发者门户中的一个安全漏洞允许攻击者在任何启用了基本身份验证的 APIM 实例上注册账户,即使管理员已在门户界面中禁用了用户注册。
该绕过可实现跨租户账户创建,从而可能允许未经授权访问 API 文档、订阅密钥以及通过开发者门户公开的其他资源。
| 日期 | 操作 |
|---|---|
| 2025-09-30 | 发现漏洞 |
| 2025-09-30 | 向 MSRC 提交初始报告 |
| 2025-10-30 | MSRC 回应:以“非漏洞”为由关闭 |
| 2025-11-01 | 向 MSRC 提交包含额外细节的第二份报告 |
| 2025-11-20 | MSRC 回应:以“设计使然”为由关闭 |
| 2025-11-20 | 报告给 CERT-FI |
| 2025-11-26 | 公开披露 |
| 2025-11-27 | 向 MITRE 申请 CVE |
| 2026-07-09 | MITRE TL-Root/CNA-LR 分配 CVE-2025-66390 |
当 Azure APIM 为开发者门户配置了基本身份验证时,管理员可以通过 Azure 门户界面禁用用户注册。然而,这只是在门户界面中隐藏了注册表单。
底层注册 API 端点仍然保持活动状态,并直接接受注册请求,从而完全绕过了界面限制。
两个问题的结合导致了该漏洞:
该攻击需要两个 APIM 实例:
步骤:
Host 头从其实例更改为目标实例关键技术细节: 跨租户绕过通过操纵注册 POST 请求中的 Host 头来实现。/signup 端点基于 Host 头处理请求,而不验证租户边界。
请求操作示例:
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]",...}}
核心问题:在界面中禁用注册并不会禁用底层 API。该 API 端点基于 Host 头接受跨租户请求。
如果满足以下条件,您的 APIM 实例存在漏洞:
如果满足以下条件,您的 APIM 实例不存在漏洞:
关键点: 在 Azure 门户界面中禁用注册是不够的。必须完全移除基本身份验证身份提供程序,才能防止跨租户注册绕过。
使用这些属性值,通过 Azure Resource Graph、ARM 模板或 Azure Policy 识别易受攻击的 APIM 实例。
| 属性路径 | 易受攻击的值 | 说明 |
|---|
基本身份验证身份提供程序是 APIM 实例下的一个独立资源:
Resource Type: Microsoft.ApiManagement/service/identityProviders
Name: basic
如果存在则易受攻击: 存在 basic 身份提供程序资源表示已配置基本身份验证。
Resource Type: Microsoft.ApiManagement/service/portalsettings/signup
Property: properties.enabled
| 属性 | 值 | 含义 |
|---|---|---|
properties.enabled | true | 界面中显示注册 |
properties.enabled | false | 界面中隐藏注册(如果存在基本身份验证,API 仍然有效!) |
使用以下查询查找可能易受攻击的 APIM 实例:
resources
| where type == "microsoft.apimanagement/service"
| where properties.developerPortalStatus == "Enabled"
| where sku.name != "Consumption"
| project name, resourceGroup, subscriptionId, location, sku.name, properties.developerPortalStatus
检查基本身份验证身份提供程序:
resources
| where type == "microsoft.apimanagement/service/identityproviders"
| where name endswith "/basic"
| project apimInstance=tostring(split(id, "/providers/Microsoft.ApiManagement/service/")[1]), resourceGroup, subscriptionId
检查开发者门户状态:
az apim show --name <apim-name> --resource-group <rg-name> --query "{name:name, portalStatus:developerPortalStatus, sku:sku.name}"
列出身份提供程序(检查 'basic'):
az apim identity-provider list --resource-group <rg-name> --service-name <apim-name> --query "[].name"
检查注册设置:
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"
关键组合: 实例存在注册绕过漏洞的条件:
properties.developerPortalStatus == 'Enabled' 且identityProviders/basic 资源存在 且portalsettings/signup.properties.enabled == false法律免责声明: 以下信息仅供识别和保护您自己组织的 Azure APIM 实例之用。未经授权访问计算机系统属违法行为。请仅测试您拥有的或已获得明确书面授权进行测试的系统。
查找带有基本身份验证注册功能的门户(最可能易受攻击):
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"
查找带有登录页面的门户(表示可能已配置基本身份验证):
site:developer.azure-api.net "Sign in" "Email" "Password" -"Azure AD" -"Microsoft account"
site:developer.azure-api.net inurl:/signin "password"
查找暴露了 API 文档的开发者门户:
site:developer.azure-api.net inurl:/apis "Subscribe"
site:developer.azure-api.net "API" "Products" "Subscribe"
常规发现:
site:*.developer.azure-api.net
inurl:developer.azure-api.net "Developer Portal"
查找 APIM 开发者门户:
http.title:"Developer Portal" http.html:"azure-api.net"
ssl.cert.subject.cn:"*.developer.azure-api.net"
http.html:"developerPortal" http.html:"azure"
发现目标后,使用 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
如果您的组织使用 Azure APIM,您可以使用以下方法识别自己的实例:
Azure 门户:
Azure CLI(适用于您的订阅):
# List all APIM instances in your subscriptions
az apim list --query "[].{name:name, resourceGroup:resourceGroup, url:developerPortalUrl}"
使用以下方法检查您组织的 APIM 实例是否存在漏洞:
使用验证脚本:
# 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
使用 Nuclei 进行内部安全审计:
# Scan your organization's APIM instances
nuclei -t azure-apim-signup-bypass.yaml -u https://YOUR-ORG.developer.azure-api.net
在审计您自己的实例时,请检查:
不构成漏洞的指标:
如果您是进行授权测试的安全专业人员:
如果您发现易受攻击的第三方 APIM 实例:
提供了一个 Python 脚本,用于检查您的 APIM 实例是否存在漏洞。
# Basic installation (HTTP probe only)
pip install requests colorama
# Full installation (includes Azure RM property checks)
pip install requests colorama azure-identity
该脚本支持两种模式:
# 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
使用 --azure 模式时,脚本直接查询 Azure Resource Manager API 以检查:
| 属性 | 易受攻击的值 |
|---|
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
提供了一个用于自动化扫描的 Nuclei 模板。
# 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 端点发送带有测试验证码数据的 POST 请求Microsoft 安全响应中心(MSRC)已两次收到关于此漏洞的通知。两份报告均以下列结论关闭:
“设计使然”
尽管绕过了管理控制并存在跨租户影响,MSRC 仍不认为这是一个安全漏洞。
apim_vuln_checker.py - Python 漏洞验证脚本azure-apim-signup-bypass.yaml - 用于自动化扫描的 Nuclei 模板README.md - 本文件Mihalis Haatainen
Bountyy Oy - 芬兰渗透测试和安全研究公司
本公告及相关工具仅供防御目的发布。请负责任地使用。
MIT 许可证 - 详情请参阅 LICENSE 文件。
properties.developerPortalStatus | Enabled | 开发者门户可访问 |
sku.name | Developer, Basic, Standard, Premium | 非 Consumption 层级(Consumption 层级的门户功能有限) |
| 条件 | 属性/资源 | 易受攻击的值 |
|---|
| 门户已启用 | properties.developerPortalStatus | == 'Enabled' |
| 非 Consumption SKU | sku.name | != 'Consumption' |
| 存在基本身份验证 | identityProviders/basic 资源 | 资源存在 |
| 注册被隐藏(存在绕过可能) | portalsettings/signup.properties.enabled | == false(存在基本身份验证时) |
properties.developerPortalStatus | == 'Enabled' |
sku.name | != 'Consumption' |
identityProviders/basic 资源 | 存在 |
portalsettings/signup.properties.enabled | == false |